diff --git a/.circleci/config.yml b/.circleci/config.yml index be6f871400d2..6b4c8af64aea 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -181,108 +181,6 @@ jobs: command: | barretenberg/cpp/scripts/ci/upload_doxygen_to_s3.sh - barretenberg-stdlib-tests: - docker: - - image: aztecprotocol/alpine-build-image - resource_class: small - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_test barretenberg-x86_64-linux-clang-assert 32 ./scripts/run_tests 1 stdlib-tests - aztec_manifest_key: barretenberg-x86_64-linux-clang-assert - - barretenberg-dsl-tests: - docker: - - image: aztecprotocol/alpine-build-image - resource_class: small - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_test barretenberg-x86_64-linux-clang-assert 32 ./scripts/run_tests 1 dsl_tests - aztec_manifest_key: barretenberg-x86_64-linux-clang-assert - - barretenberg-tests: - docker: - - image: aztecprotocol/alpine-build-image - resource_class: small - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_test barretenberg-x86_64-linux-clang-assert 32 ./scripts/bb-tests.sh - aztec_manifest_key: barretenberg-x86_64-linux-clang-assert - - barretenberg-avm-tests: - docker: - - image: aztecprotocol/alpine-build-image - resource_class: small - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_test barretenberg-x86_64-linux-clang-assert 32 ./scripts/avm-tests.sh - aztec_manifest_key: barretenberg-x86_64-linux-clang-assert - - barretenberg-bench: - machine: - # NOTE: we usually use alpine build image when making spot images, but - # we are not able to upload to S3 with it - image: default - resource_class: medium - steps: - - *checkout - - *setup_env - - run: - name: "Benchmark" - command: cond_spot_run_build barretenberg-bench 32 - aztec_manifest_key: barretenberg-bench - - run: - name: "Upload" - command: | - barretenberg/cpp/scripts/ci/upload_benchmarks_to_s3.sh - - barretenberg-proof-system-tests: - docker: - - image: aztecprotocol/alpine-build-image - resource_class: small - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_test barretenberg-x86_64-linux-clang-assert 32 ./scripts/run_tests 1 stdlib_circuit_builders_tests - aztec_manifest_key: barretenberg-x86_64-linux-clang-assert - - barretenberg-stdlib-plonk-recursion-ultra-tests: - docker: - - image: aztecprotocol/alpine-build-image - resource_class: small - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_test barretenberg-x86_64-linux-clang-assert 32 ./scripts/run_tests 3 stdlib_plonk_recursion_tests --gtest_filter=-*turbo* - aztec_manifest_key: barretenberg-x86_64-linux-clang-assert - - barretenberg-stdlib-honk-recursion-ultra-tests: - docker: - - image: aztecprotocol/alpine-build-image - resource_class: small - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_test barretenberg-x86_64-linux-clang-assert 32 ./scripts/run_tests 3 stdlib_honk_recursion_tests - aztec_manifest_key: barretenberg-x86_64-linux-clang-assert - bb-js: machine: image: default @@ -629,166 +527,40 @@ jobs: command: build end-to-end aztec_manifest_key: end-to-end - e2e-tests: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_container end-to-end 64 ./src/e2e* - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test + # For old e2e tests see yarn-project/end-to-end/Earthfile + # Semantics are similar to Dockerfile - e2e-sandbox-example: + # NOTE: Unlike other e2e, these will be re-enabled here as currently the logs functionality is not in the new earthfile setup + bench-publish-rollup: steps: - *checkout - *setup_env - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=composed/e2e_sandbox_example.test.ts - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - uniswap-trade-on-l1-from-l2: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=composed/uniswap_trade_on_l1_from_l2.test.ts - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - integration-l1-publisher: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=composed/integration_l1_publisher.test.ts - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - e2e-persistence: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=composed/e2e_persistence.test.ts - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - e2e-browser: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=composed/e2e_aztec_js_browser.test.ts - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - pxe: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=composed/pxe.test.ts - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - cli-docs-sandbox: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=composed/cli_docs_sandbox.test.ts - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - e2e-docs-examples: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=composed/docs_examples.test.ts - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - guides-writing-an-account-contract: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=guides/writing_an_account_contract.test.ts - aztec_manifest_key: end-to-end - <<: *defaults_e2e_test - - guides-dapp-testing: - steps: - - *checkout - - *setup_env - - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=guides/dapp_testing.test.ts + name: "Benchmark" + command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_publish_rollup.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees aztec_manifest_key: end-to-end <<: *defaults_e2e_test - guides-sample-dapp: + bench-process-history: steps: - *checkout - *setup_env - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=sample-dapp + name: "Benchmark" + command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_process_history.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees aztec_manifest_key: end-to-end <<: *defaults_e2e_test - guides-up-quick-start: + bench-tx-size: steps: - *checkout - *setup_env - run: - name: "Test" - command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose.yml TEST=guides/up_quick_start.test.ts + name: "Benchmark" + command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_tx_size_fees.test.ts ENABLE_GAS=1 DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees aztec_manifest_key: end-to-end <<: *defaults_e2e_test - # bench-publish-rollup: - # steps: - # - *checkout - # - *setup_env - # - run: - # name: "Benchmark" - # command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_publish_rollup.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees - # aztec_manifest_key: end-to-end - # <<: *defaults_e2e_test - - # bench-process-history: - # steps: - # - *checkout - # - *setup_env - # - run: - # name: "Benchmark" - # command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_process_history.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees - # aztec_manifest_key: end-to-end - # <<: *defaults_e2e_test - - # bench-tx-size: - # steps: - # - *checkout - # - *setup_env - # - run: - # name: "Benchmark" - # command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_tx_size_fees.test.ts ENABLE_GAS=1 DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees - # aztec_manifest_key: end-to-end - # <<: *defaults_e2e_test - build-docs: machine: image: default @@ -807,18 +579,6 @@ jobs: echo "Deploying docs" docs/deploy_netlify.sh $BRANCH $PULL_REQUEST - yellow-paper: - machine: - image: default - resource_class: large - steps: - - *checkout - - *setup_env - - run: - name: "Build yellow paper" - command: build yellow-paper - aztec_manifest_key: yellow-paper - e2e-join: docker: - image: cimg/base:2023.09 @@ -837,15 +597,15 @@ jobs: name: "Noop" command: echo Noop - # bench-summary: - # machine: - # image: default - # steps: - # - *checkout - # - *setup_env - # - run: - # name: "Assemble benchmark summary from uploaded logs" - # command: ./scripts/ci/assemble_e2e_benchmark.sh + bench-summary: + machine: + image: default + steps: + - *checkout + - *setup_env + - run: + name: "Assemble benchmark summary from uploaded logs" + command: ./scripts/ci/assemble_e2e_benchmark.sh # Deploy & release jobs. deploy-and-release: @@ -869,6 +629,7 @@ jobs: command: | should_deploy || exit 0 deploy_terraform_services iac/mainnet-fork mainnet-fork mainnet-fork aws_efs_file_system.aztec_mainnet_fork_data_store + ./iac/mainnet-fork/scripts/wait_for_fork - run: name: "Release canary to NPM: bb.js" command: | @@ -1035,17 +796,6 @@ workflows: - barretenberg-x86_64-linux-clang-fuzzing: *defaults - barretenberg-wasm-linux-clang: *defaults - barretenberg-x86_64-linux-clang-sol: *defaults - - barretenberg-bench: - requires: - - barretenberg-x86_64-linux-clang - <<: *defaults - - barretenberg-proof-system-tests: *bb_test - - barretenberg-dsl-tests: *bb_test - - barretenberg-tests: *bb_test - - barretenberg-avm-tests: *bb_test - - barretenberg-stdlib-tests: *bb_test - - barretenberg-stdlib-plonk-recursion-ultra-tests: *bb_test - - barretenberg-stdlib-honk-recursion-ultra-tests: *bb_test - barretenberg-acir-tests-bb: *bb_acir_tests - barretenberg-acir-tests-bb-sol: requires: @@ -1072,8 +822,6 @@ workflows: - mainnet-fork: *defaults - - yellow-paper: *defaults - - noir-projects: requires: - avm-transpiler @@ -1126,19 +874,6 @@ workflows: - aztec-package - cli <<: *defaults - - e2e-tests: *e2e_test - - cli-docs-sandbox: *e2e_test - - e2e-docs-examples: *e2e_test - - e2e-browser: *e2e_test - - e2e-persistence: *e2e_test - - e2e-sandbox-example: *e2e_test - - integration-l1-publisher: *e2e_test - - pxe: *e2e_test - - uniswap-trade-on-l1-from-l2: *e2e_test - - guides-writing-an-account-contract: *e2e_test - - guides-dapp-testing: *e2e_test - - guides-sample-dapp: *e2e_test - - guides-up-quick-start: *e2e_test # Everything that must complete before deployment. - end: @@ -1149,50 +884,29 @@ workflows: - barretenberg-x86_64-linux-clang-fuzzing - barretenberg-wasm-linux-clang - barretenberg-x86_64-linux-clang-sol - - barretenberg-bench - - barretenberg-proof-system-tests - - barretenberg-dsl-tests - - barretenberg-tests - - barretenberg-avm-tests - - barretenberg-stdlib-tests - - barretenberg-stdlib-plonk-recursion-ultra-tests - - barretenberg-stdlib-honk-recursion-ultra-tests - barretenberg-acir-tests-bb - barretenberg-acir-tests-bb-sol - barretenberg-docs - build-docs - mainnet-fork - - e2e-tests - - cli-docs-sandbox - - e2e-docs-examples - - e2e-browser - - e2e-persistence - - e2e-sandbox-example - - integration-l1-publisher - - pxe - - uniswap-trade-on-l1-from-l2 - - guides-writing-an-account-contract - - guides-dapp-testing - - guides-sample-dapp - - guides-up-quick-start - boxes-vanilla - boxes-react - - yellow-paper - noir-packages-tests - yarn-project-test - prover-client-test + - e2e-join <<: *defaults # Benchmark jobs. - # - bench-publish-rollup: *e2e_test - # - bench-process-history: *e2e_test - # - bench-tx-size: *e2e_test - # - bench-summary: - # requires: - # - bench-publish-rollup - # - bench-process-history - # - bench-tx-size - # <<: *defaults + - bench-publish-rollup: *e2e_test + - bench-process-history: *e2e_test + - bench-tx-size: *e2e_test + - bench-summary: + requires: + - bench-publish-rollup + - bench-process-history + - bench-tx-size + <<: *defaults # Production releases. - deploy-and-release: *defaults_deploy diff --git a/.github/ci-setup-action/action.yml b/.github/ci-setup-action/action.yml index 4eba68046b3f..e96dfd29a7c1 100644 --- a/.github/ci-setup-action/action.yml +++ b/.github/ci-setup-action/action.yml @@ -64,5 +64,5 @@ runs: echo "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" > "/run/${{ inputs.concurrency_key }}.lock" echo "/run/${{ inputs.concurrency_key }}.lock acquired." post: | - rm "/run/${{ inputs.concurrency_key }}.lock" + rm "/run/${{ inputs.concurrency_key }}.lock" || true echo "/run/${{ inputs.concurrency_key }}.lock removed." diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1d67fb668b3..8ad90c704691 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,13 +40,11 @@ jobs: - uses: ./.github/ci-setup-action with: dockerhub_password: "${{ secrets.DOCKERHUB_PASSWORD }}" - concurrency_token: "${{ secrets.AZTEC_GITHUB_TOKEN }}" - # must be globally unique for build x runner concurrency_key: build-${{ github.actor }}-x86 # prepare images locally, tagged by commit hash - name: "Build E2E Image" timeout-minutes: 40 - run: earthly ./yarn-project+export-end-to-end + run: earthly-ci ./yarn-project+export-end-to-end # We base our e2e list used in e2e-x86 off the targets in ./yarn-project/end-to-end # (Note ARM uses just 2 tests as a smoketest) - name: Create list of end-to-end jobs @@ -66,18 +64,17 @@ jobs: - uses: ./.github/ci-setup-action with: dockerhub_password: "${{ secrets.DOCKERHUB_PASSWORD }}" - concurrency_token: "${{ secrets.AZTEC_GITHUB_TOKEN }}" # must be globally unique for build x runner concurrency_key: e2e-${{ github.actor }}-x86-${{ matrix.test }} - name: Test working-directory: ./yarn-project/end-to-end/ timeout-minutes: 25 - run: earthly -P --no-output +${{ matrix.test }} --e2e_mode=cache + run: earthly-ci -P --no-output +${{ matrix.test }} --e2e_mode=cache # TODO # - name: Upload logs # run: BRANCH=${{ github.ref_name }} PULL_REQUEST=${{ github.event.number }} scripts/ci/upload_logs_to_s3 ./yarn-project/end-to-end/log - # barretenberg (prover) native tests + # barretenberg (prover) native and AVM (public VM) tests # only ran on x86 for resource reasons (memory intensive) bb-native-tests: needs: setup @@ -90,13 +87,13 @@ jobs: - uses: ./.github/ci-setup-action with: dockerhub_password: "${{ secrets.DOCKERHUB_PASSWORD }}" - concurrency_token: "${{ secrets.AZTEC_GITHUB_TOKEN }}" # must be globally unique for build x runner concurrency_key: bb-native-tests-${{ github.actor }}-x86 - name: "Native Prover Tests" working-directory: ./barretenberg/cpp/ timeout-minutes: 25 - run: earthly --no-output +test + # limit our parallelism to half our cores + run: earthly-ci --no-output +test --hardware_concurrency=64 # push benchmarking binaries to dockerhub registry bb-bench-binaries: @@ -107,14 +104,12 @@ jobs: - uses: ./.github/ci-setup-action with: dockerhub_password: "${{ secrets.DOCKERHUB_PASSWORD }}" - concurrency_token: "${{ secrets.AZTEC_GITHUB_TOKEN }}" - # must be globally unique for build x runner concurrency_key: bb-bench-binaries-${{ github.actor }}-x86 - name: Build and Push Binaries if: ${{ github.event.inputs.just_start_spot != 'true' }} timeout-minutes: 15 working-directory: ./barretenberg/cpp/ - run: earthly --push +bench-binaries + run: earthly-ci --push +bench-binaries setup-bench: uses: ./.github/workflows/setup-runner.yml @@ -137,35 +132,35 @@ jobs: - uses: ./.github/ci-setup-action with: dockerhub_password: "${{ secrets.DOCKERHUB_PASSWORD }}" - concurrency_token: "${{ secrets.AZTEC_GITHUB_TOKEN }}" - # must be globally unique for build x runner - # technically not needed as we only make one GA runner, but a backup concurrency_key: bb-bench-${{ github.actor }}-bench-x86 # Use bench_mode=cache to read the pushed build above - name: Client IVC Bench working-directory: ./barretenberg/cpp/ timeout-minutes: 15 - run: earthly --no-output +bench-client-ivc --bench_mode=cache + run: earthly-ci --no-output +bench-client-ivc --bench_mode=cache - name: Ultrahonk Bench working-directory: ./barretenberg/cpp/ timeout-minutes: 15 - run: earthly --no-output +bench-ultra-honk --bench_mode=cache - - # # Post actions, deploy and summarize logs - # aztec-bench-summary: - # runs-on: ${{ github.actor }} - # # IMPORTANT security flaw if we don't need 'check-run-condition' - # needs: e2e-x86 - # concurrency: - # group: aztec-bench-summary-${{ github.ref_name == 'master' && github.run_id || github.ref_name }}-x86 - # cancel-in-progress: true - # steps: - # - name: Checkout - # uses: actions/checkout@v4 - # with: - # ref: ${{ github.event.pull_request.head.sha }} + run: earthly-ci --no-output +bench-ultra-honk --bench_mode=cache - # - name: "Assemble benchmark summary from uploaded logs" - # command: ./scripts/ci/assemble_e2e_benchmark_earthly.sh + merge-check: + runs-on: ${{ github.actor }}-x86 + needs: [e2e, bb-native-tests, bb-bench] + steps: + - run: echo Pull request merging now allowed. + notify: + needs: [e2e, bb-native-tests, bb-bench] + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/master' && failure() }} + steps: + - name: Send notification to aztec3-ci channel if workflow failed on master + uses: slackapi/slack-github-action@v1.25.0 + with: + payload: | + { + "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_NOTIFY_WORKFLOW_TRIGGER_URL }} diff --git a/.github/workflows/setup-runner.yml b/.github/workflows/setup-runner.yml index 9f544f4f3675..c581738eaceb 100644 --- a/.github/workflows/setup-runner.yml +++ b/.github/workflows/setup-runner.yml @@ -3,7 +3,7 @@ # just for the CI job. These are specced per user and run the entire CI. # TODO These have a persistent EBS volume that forms a fast-online docker image cache (used by Earthly), meaning # TODO build steps that ran in previous invocations are quickly ran from cache. -name: Reusable Spot Instance and Setup Workflow +name: Setup Runner and CI on: workflow_call: inputs: @@ -52,9 +52,12 @@ on: jobs: start-builder: runs-on: ubuntu-latest + # we want to avoid race conditions when making spot across multiple PRs as we only use one runner + concurrency: + group: start-builder-${{ inputs.runner_label }} steps: - name: Start EC2 runner - uses: AztecProtocol/ec2-action-builder@v0.6 + uses: AztecProtocol/ec2-action-builder@v0.13 with: github_token: ${{ secrets.GH_SELF_HOSTED_RUNNER_TOKEN }} aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} @@ -69,6 +72,7 @@ jobs: ec2_instance_type: ${{ inputs.ec2_instance_type }} ec2_ami_id: ${{ inputs.ec2_ami_id }} ec2_instance_ttl: ${{ inputs.ec2_instance_ttl }} + ec2_key_name: "build-instance" ec2_instance_tags: '[{"Key": "Keep-Alive", "Value": "true"}]' setup: @@ -107,7 +111,7 @@ jobs: - name: Run Docker Prune # helps to not overuse space - run: docker system prune -f + run: docker system prune -f || true - name: Run Earthly Bootstrap run: earthly bootstrap diff --git a/.github/workflows/start-spot.yml b/.github/workflows/start-spot.yml new file mode 100644 index 000000000000..f6b532935faf --- /dev/null +++ b/.github/workflows/start-spot.yml @@ -0,0 +1,28 @@ +# Useful if the spot runners are in a bad state +name: Start Personal Spot +on: + workflow_dispatch: {} +jobs: + stop-build-x86: + uses: ./.github/workflows/setup-runner.yml + with: + runner_label: ${{ github.actor }}-x86 + ebs_cache_size_gb: 256 + runner_concurrency: 50 + subaction: start + ec2_instance_type: m6a.32xlarge + ec2_ami_id: ami-04d8422a9ba4de80f + ec2_instance_ttl: 40 # refreshed by jobs + secrets: inherit + + stop-bench: + uses: ./.github/workflows/setup-runner.yml + with: + runner_label: ${{ github.actor }}-bench-x86 + ebs_cache_size_gb: 64 + runner_concurrency: 1 + subaction: start + ec2_instance_type: m6a.4xlarge + ec2_ami_id: ami-04d8422a9ba4de80f + ec2_instance_ttl: 15 # refreshed by jobs + secrets: inherit diff --git a/.noir-sync-commit b/.noir-sync-commit index 64da23777cd7..8f6aafb96d3a 100644 --- a/.noir-sync-commit +++ b/.noir-sync-commit @@ -1 +1 @@ -1d96937a8e94a91c0c17c97102498d067fca76c3 +6cc105ee441e093b4fccdd5fcc3db922eb28a3fb diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b1b5f363765d..2af8fe1250f3 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,7 +1,7 @@ { - ".": "0.34.0", - "yarn-project/cli": "0.34.0", - "yarn-project/aztec": "0.34.0", - "barretenberg": "0.34.0", - "barretenberg/ts": "0.34.0" + ".": "0.35.1", + "yarn-project/cli": "0.35.1", + "yarn-project/aztec": "0.35.1", + "barretenberg": "0.35.1", + "barretenberg/ts": "0.35.1" } diff --git a/.vscode/settings.json b/.vscode/settings.json index 21f55227f992..ea41bbe2bc22 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -125,10 +125,6 @@ "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, - // Now when a new file is pasted in /yellow-paper/docs/readme.md, the image file is created at /yellow-paper/docs/images/readme/image.png. - "markdown.copyFiles.destination": { - "/yellow-paper/**/*": "images/${documentBaseName}/" - }, /////////////////////////////////////// // C++/Circuits settings /////////////////////////////////////// @@ -169,5 +165,6 @@ "**/target/**": true, "**/l1-contracts/lib/**": true, "**/barretenberg/cpp/build*/**": true - } + }, + "cmake.sourceDirectory": "/mnt/user-data/adam/aztec-packages/barretenberg/cpp" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 1932869d808a..18ca6ac87370 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,156 @@ # Changelog +## [0.35.1](https://github.com/AztecProtocol/aztec-packages/compare/aztec-packages-v0.35.0...aztec-packages-v0.35.1) (2024-04-16) + + +### Bug Fixes + +* Disable bench-tx-size until fixed ([#5789](https://github.com/AztecProtocol/aztec-packages/issues/5789)) ([9a85c20](https://github.com/AztecProtocol/aztec-packages/commit/9a85c205f3a539494dc57fc7abb7c7700ad3a3df)) + +## [0.35.0](https://github.com/AztecProtocol/aztec-packages/compare/aztec-packages-v0.34.0...aztec-packages-v0.35.0) (2024-04-16) + + +### ⚠ BREAKING CHANGES + +* Use fixed size arrays in black box functions where sizes are known ([#5620](https://github.com/AztecProtocol/aztec-packages/issues/5620)) +* trap with revert data ([#5732](https://github.com/AztecProtocol/aztec-packages/issues/5732)) +* **acir:** BrilligCall opcode ([#5709](https://github.com/AztecProtocol/aztec-packages/issues/5709)) +* rename request_max_block_number ([#5675](https://github.com/AztecProtocol/aztec-packages/issues/5675)) +* pay fee for account init ([#5601](https://github.com/AztecProtocol/aztec-packages/issues/5601)) + +### Features + +* **acir:** BrilligCall opcode ([#5709](https://github.com/AztecProtocol/aztec-packages/issues/5709)) ([f06f64c](https://github.com/AztecProtocol/aztec-packages/commit/f06f64c451333d36eb05951202d69ee85cca8851)) +* Add serialisation methods ([#5749](https://github.com/AztecProtocol/aztec-packages/issues/5749)) ([20d290c](https://github.com/AztecProtocol/aztec-packages/commit/20d290c38fe4589b4bdafc6c529d6fd903d596e4)) +* App siloing in new key store ([#5721](https://github.com/AztecProtocol/aztec-packages/issues/5721)) ([ae37d32](https://github.com/AztecProtocol/aztec-packages/commit/ae37d32ce58417eaa5345f2b77f92f1dfe6709d1)), closes [#5635](https://github.com/AztecProtocol/aztec-packages/issues/5635) +* **avm-simulator:** Plumb noir assertion messages ([#5774](https://github.com/AztecProtocol/aztec-packages/issues/5774)) ([2cf11ac](https://github.com/AztecProtocol/aztec-packages/commit/2cf11ac76805b8d648a4b32d7cd6446eb31b9a35)) +* **avm:** CMOV opcode ([#5575](https://github.com/AztecProtocol/aztec-packages/issues/5575)) ([19dbe46](https://github.com/AztecProtocol/aztec-packages/commit/19dbe46bce95221bf2e68c9361618998a6bdc64f)), closes [#5557](https://github.com/AztecProtocol/aztec-packages/issues/5557) +* **avm:** Enable contract testing with bb binary ([#5584](https://github.com/AztecProtocol/aztec-packages/issues/5584)) ([d007d79](https://github.com/AztecProtocol/aztec-packages/commit/d007d79c7014261d9c663e28c948600d92e85759)) +* **avm:** Enable range check on the ALU registers ([#5696](https://github.com/AztecProtocol/aztec-packages/issues/5696)) ([202fc1b](https://github.com/AztecProtocol/aztec-packages/commit/202fc1b750e83f91c32b128b981db1c5c92ef3f2)) +* **avm:** Keccak as blackbox function ([#5722](https://github.com/AztecProtocol/aztec-packages/issues/5722)) ([6ea677a](https://github.com/AztecProtocol/aztec-packages/commit/6ea677aa97e6a597f5c6b580e655143ffeddbccf)) +* **avm:** Poseidon2_permutation as black box ([#5707](https://github.com/AztecProtocol/aztec-packages/issues/5707)) ([5526b36](https://github.com/AztecProtocol/aztec-packages/commit/5526b36721a57b143ff8d0f381f94be275ccf59c)) +* **avm:** Sha256 as blackbox function ([#5727](https://github.com/AztecProtocol/aztec-packages/issues/5727)) ([cac9cba](https://github.com/AztecProtocol/aztec-packages/commit/cac9cba8974a4923bce9e8f4627e2654bfab4f81)) +* **avm:** Take sizeOffset in CALL ([#5763](https://github.com/AztecProtocol/aztec-packages/issues/5763)) ([95eadd6](https://github.com/AztecProtocol/aztec-packages/commit/95eadd67a72a286f07876f80586e6d57605d0af5)) +* Brillig heterogeneous memory cells ([#5608](https://github.com/AztecProtocol/aztec-packages/issues/5608)) ([3287aa2](https://github.com/AztecProtocol/aztec-packages/commit/3287aa29c1e85dd89d5ae9f73bffa9406cc47d08)) +* Change public nullifiers api ([#5660](https://github.com/AztecProtocol/aztec-packages/issues/5660)) ([986e7f9](https://github.com/AztecProtocol/aztec-packages/commit/986e7f924e9af6461e3e88de29f22cf2a8f45c4e)) +* Changing finite field arithmetic in wasm to 29 bits for multiplications ([#5435](https://github.com/AztecProtocol/aztec-packages/issues/5435)) ([b2d9b9d](https://github.com/AztecProtocol/aztec-packages/commit/b2d9b9d5f1764b159e081b3cc9806ee83fdf341f)) +* **ci:** Turn on new CI as mandatory ([#5761](https://github.com/AztecProtocol/aztec-packages/issues/5761)) ([bebed32](https://github.com/AztecProtocol/aztec-packages/commit/bebed32272e0974de21b5c7d21344d3cf1597a24)) +* **docs:** Merge yellow paper into docs protocol specs section ([#5668](https://github.com/AztecProtocol/aztec-packages/issues/5668)) ([66dc509](https://github.com/AztecProtocol/aztec-packages/commit/66dc5091b2aff53580e1a313e1001369ffc87e6b)) +* E2e token contract can run in 2m with snapshots and test separation. ([#5526](https://github.com/AztecProtocol/aztec-packages/issues/5526)) ([b0037dd](https://github.com/AztecProtocol/aztec-packages/commit/b0037dd051bd0312abe79d686cd93231cfe63d56)) +* Export poseidon2_permutation and add to foundation/crypto ([#5706](https://github.com/AztecProtocol/aztec-packages/issues/5706)) ([6b91e27](https://github.com/AztecProtocol/aztec-packages/commit/6b91e2776de8fd5b1f489b5cfeee83c7e0996c2e)) +* Get last mock oracles params (https://github.com/noir-lang/noir/pull/4789) ([825c455](https://github.com/AztecProtocol/aztec-packages/commit/825c455a62faeae5d148ce4f914efacb8f4c50fd)) +* Impl of missing functionality in new key store ([#5750](https://github.com/AztecProtocol/aztec-packages/issues/5750)) ([af49a29](https://github.com/AztecProtocol/aztec-packages/commit/af49a290722c3430ad26a458cfb489b8b4ea7604)) +* LT/LTE for AVM ([#5559](https://github.com/AztecProtocol/aztec-packages/issues/5559)) ([350abeb](https://github.com/AztecProtocol/aztec-packages/commit/350abeb4c88d7e7878abc32e9263c558633f0df9)) +* New key store ([#5653](https://github.com/AztecProtocol/aztec-packages/issues/5653)) ([3e44a58](https://github.com/AztecProtocol/aztec-packages/commit/3e44a580a3769d7e65124294500ccedab9cdfce4)), closes [#5607](https://github.com/AztecProtocol/aztec-packages/issues/5607) +* Pay fee for account init ([#5601](https://github.com/AztecProtocol/aztec-packages/issues/5601)) ([aca804f](https://github.com/AztecProtocol/aztec-packages/commit/aca804f96ca9e74b6b553449333e195c0639b151)) +* Poseidon separator ([#5717](https://github.com/AztecProtocol/aztec-packages/issues/5717)) ([d5256d2](https://github.com/AztecProtocol/aztec-packages/commit/d5256d29f3bc7d2094ba760c5a528dd61475bb40)) +* Proving the rollup circuits ([#5599](https://github.com/AztecProtocol/aztec-packages/issues/5599)) ([145cbcd](https://github.com/AztecProtocol/aztec-packages/commit/145cbcda61fd73f4e135348b31c59c774cfae965)) +* Public Kernel proving orchestration ([#5748](https://github.com/AztecProtocol/aztec-packages/issues/5748)) ([2ae0ee5](https://github.com/AztecProtocol/aztec-packages/commit/2ae0ee537b37c444f59b8255bd856f4da2ef818f)) +* Rename request_max_block_number ([#5675](https://github.com/AztecProtocol/aztec-packages/issues/5675)) ([c695fcd](https://github.com/AztecProtocol/aztec-packages/commit/c695fcd91041a4ba9fd1d38b170993612c5e2ad1)) +* Separate nullfier_inclusion checks for private/public/avm ([#5657](https://github.com/AztecProtocol/aztec-packages/issues/5657)) ([e4d2df6](https://github.com/AztecProtocol/aztec-packages/commit/e4d2df6b0b5592fe847e3c47020455ac8003d84d)) +* Sequencer validates setup/teardown function selectors ([#5649](https://github.com/AztecProtocol/aztec-packages/issues/5649)) ([8f8ad56](https://github.com/AztecProtocol/aztec-packages/commit/8f8ad56471617d611317b96f04cf13f2edc2b493)), closes [#5401](https://github.com/AztecProtocol/aztec-packages/issues/5401) +* Shared mutable storage ([#5490](https://github.com/AztecProtocol/aztec-packages/issues/5490)) ([c4e41a9](https://github.com/AztecProtocol/aztec-packages/commit/c4e41a9809e0a6de87a95c78ba3b71aff81da64a)) +* **simulator:** Fetch return values at circuit execution ([#5642](https://github.com/AztecProtocol/aztec-packages/issues/5642)) ([413a4e0](https://github.com/AztecProtocol/aztec-packages/commit/413a4e0e4e22c0dcf86a2d3de6b75c98ae1d67d4)) +* Split `backend_barretenburg` into prover and verifier classes (https://github.com/noir-lang/noir/pull/4769) ([825c455](https://github.com/AztecProtocol/aztec-packages/commit/825c455a62faeae5d148ce4f914efacb8f4c50fd)) +* Sync from aztec-packages (https://github.com/noir-lang/noir/pull/4764) ([1eb288e](https://github.com/AztecProtocol/aztec-packages/commit/1eb288e9adc8b803e75ed80317c3e0979d0dfdee)) +* Sync from aztec-packages (https://github.com/noir-lang/noir/pull/4787) ([825c455](https://github.com/AztecProtocol/aztec-packages/commit/825c455a62faeae5d148ce4f914efacb8f4c50fd)) +* Trap with revert data ([#5732](https://github.com/AztecProtocol/aztec-packages/issues/5732)) ([f849575](https://github.com/AztecProtocol/aztec-packages/commit/f84957584ff76c22c069903f7648735a0be91d7f)) +* Unroll loops iteratively (https://github.com/noir-lang/noir/pull/4779) ([1eb288e](https://github.com/AztecProtocol/aztec-packages/commit/1eb288e9adc8b803e75ed80317c3e0979d0dfdee)) +* Update circuits structs with gas info ([#5677](https://github.com/AztecProtocol/aztec-packages/issues/5677)) ([3db6dd1](https://github.com/AztecProtocol/aztec-packages/commit/3db6dd1a213d5f6de8a5e79511ecce9f072b3d41)) +* Use fixed size arrays in black box functions where sizes are known ([#5620](https://github.com/AztecProtocol/aztec-packages/issues/5620)) ([f50b180](https://github.com/AztecProtocol/aztec-packages/commit/f50b180379ac90d782aba3472708f8cef122c25b)) +* Variable length returns ([#5633](https://github.com/AztecProtocol/aztec-packages/issues/5633)) ([b4a6f17](https://github.com/AztecProtocol/aztec-packages/commit/b4a6f174e2b88f5e4fed128752fc0c30d919084d)) +* Wire AVM gas used to public kernel ([#5740](https://github.com/AztecProtocol/aztec-packages/issues/5740)) ([4f55d10](https://github.com/AztecProtocol/aztec-packages/commit/4f55d1023b07df6bf4fc83b6ecb0024426585d0a)) + + +### Bug Fixes + +* "feat: Changing finite field arithmetic in wasm to 29 bits for multiplications" ([#5779](https://github.com/AztecProtocol/aztec-packages/issues/5779)) ([bcfee97](https://github.com/AztecProtocol/aztec-packages/commit/bcfee97da99c654f8641ab8099bbbe5d58e2a5c7)) +* Anvil start retry in case something bad. Fix colors. ([#5673](https://github.com/AztecProtocol/aztec-packages/issues/5673)) ([0b6b6f6](https://github.com/AztecProtocol/aztec-packages/commit/0b6b6f64ab5984cc8dbaeb1b80136ce1c8a1e3b7)) +* ArrayGet and Set are not pure (https://github.com/noir-lang/noir/pull/4783) ([825c455](https://github.com/AztecProtocol/aztec-packages/commit/825c455a62faeae5d148ce4f914efacb8f4c50fd)) +* Avoid get row in databus ([#5742](https://github.com/AztecProtocol/aztec-packages/issues/5742)) ([d67b6c8](https://github.com/AztecProtocol/aztec-packages/commit/d67b6c8bb703d856c0d95d4d47cc6de93467e9ab)) +* Avoid huge unrolling in hash_args ([#5703](https://github.com/AztecProtocol/aztec-packages/issues/5703)) ([10d9ad9](https://github.com/AztecProtocol/aztec-packages/commit/10d9ad99200a5897417ff5669763ead4e38d87fa)) +* **ci,noir-projects:** Bring apt-get higher in cache ([#5775](https://github.com/AztecProtocol/aztec-packages/issues/5775)) ([d37cbb9](https://github.com/AztecProtocol/aztec-packages/commit/d37cbb95cfbb773242bda568f8a7a0b066edc437)) +* **ci:** 192 core spot runner ([#5767](https://github.com/AztecProtocol/aztec-packages/issues/5767)) ([37daac6](https://github.com/AztecProtocol/aztec-packages/commit/37daac6a4547d70d06714e1cd727eddbe297cf64)) +* **ci:** Bigger cache disk, cache+prune docker images, disable ClientIvcTests.Full ([#5729](https://github.com/AztecProtocol/aztec-packages/issues/5729)) ([5dcbd75](https://github.com/AztecProtocol/aztec-packages/commit/5dcbd75c0795640d48592efbd750cd22b5e5ddd5)) +* **ci:** Builder types ([#5711](https://github.com/AztecProtocol/aztec-packages/issues/5711)) ([b16f169](https://github.com/AztecProtocol/aztec-packages/commit/b16f16967ac3d99fc6a23c92dec7e7dd8535adf7)) +* **ci:** Cache size not honoured ([#5738](https://github.com/AztecProtocol/aztec-packages/issues/5738)) ([d4ff340](https://github.com/AztecProtocol/aztec-packages/commit/d4ff340745456df31f1554588c3c41d9fa2f1fa6)) +* **ci:** Don't fail if can't prune ([d9bb2c7](https://github.com/AztecProtocol/aztec-packages/commit/d9bb2c7fc561a7b1c7dfb516a5afc107cc8bdbbd)) +* **ci:** Error in spot ([#5745](https://github.com/AztecProtocol/aztec-packages/issues/5745)) ([4d754aa](https://github.com/AztecProtocol/aztec-packages/commit/4d754aa9a76a9673ea50819e4d9a7e2e04944829)) +* **ci:** Fix arm e2e references, spot shutdown ([#5741](https://github.com/AztecProtocol/aztec-packages/issues/5741)) ([1c4667c](https://github.com/AztecProtocol/aztec-packages/commit/1c4667cc58a2eda323ae51f85cfc4223d3eb143d)) +* **ci:** Hotfix arm ([1ddb1c7](https://github.com/AztecProtocol/aztec-packages/commit/1ddb1c7136225d874d9d135d354ff601695cc590)) +* **ci:** Hotfix just one ARM task ([10f27ae](https://github.com/AztecProtocol/aztec-packages/commit/10f27ae0aa856d1eebede71169a93a23313fe617)) +* **ci:** Speculative deploy fix ([9a9eab6](https://github.com/AztecProtocol/aztec-packages/commit/9a9eab6b6b4e087ef1c15172c974353f90815b8b)) +* **ci:** Wait for mainnet fork deployment ([#5735](https://github.com/AztecProtocol/aztec-packages/issues/5735)) ([8f3794d](https://github.com/AztecProtocol/aztec-packages/commit/8f3794dad170dba616c505d85bc1731fb6177ce0)) +* **ci:** Wait_for_fork env var ([#5780](https://github.com/AztecProtocol/aztec-packages/issues/5780)) ([d85267b](https://github.com/AztecProtocol/aztec-packages/commit/d85267b7f1c34bf93087f3a48690ddfd8a9cf05d)) +* Correct ICE panic messages in brillig `convert_black_box_call` (https://github.com/noir-lang/noir/pull/4761) ([1eb288e](https://github.com/AztecProtocol/aztec-packages/commit/1eb288e9adc8b803e75ed80317c3e0979d0dfdee)) +* Disable flakey vanilla recursion test ([#5672](https://github.com/AztecProtocol/aztec-packages/issues/5672)) ([f84f7b6](https://github.com/AztecProtocol/aztec-packages/commit/f84f7b68f6c8072480127a065def1c4453e55877)) +* Don't run e2e tests against wrong anvil ([#5686](https://github.com/AztecProtocol/aztec-packages/issues/5686)) ([9ff45f6](https://github.com/AztecProtocol/aztec-packages/commit/9ff45f69af562db4cec69c6231659476667f1cf9)) +* Dont error in bench summary ([#5693](https://github.com/AztecProtocol/aztec-packages/issues/5693)) ([470b0f3](https://github.com/AztecProtocol/aztec-packages/commit/470b0f36138f34fcff1da869f7fd54f2d50c1480)) +* E2e getStack, disable failing e2e ([#5768](https://github.com/AztecProtocol/aztec-packages/issues/5768)) ([e5f3ece](https://github.com/AztecProtocol/aztec-packages/commit/e5f3ece131b16aeede897f0a9bb3ecc23cb4d9dc)) +* GA concurrency ([#5713](https://github.com/AztecProtocol/aztec-packages/issues/5713)) ([eac2585](https://github.com/AztecProtocol/aztec-packages/commit/eac25853cc8ca14254010076106b6a9555ef5d17)) +* Generate_aztecnr_reference.js not getting generics or multi-line params ([#5679](https://github.com/AztecProtocol/aztec-packages/issues/5679)) ([a22bc3d](https://github.com/AztecProtocol/aztec-packages/commit/a22bc3d4004b050449569bf66fe7431ccd04a16c)) +* Hotfix submodule cache ([92b92b3](https://github.com/AztecProtocol/aztec-packages/commit/92b92b32c46f7c4d332a372c0e1039040c762eff)) +* Hotfix underspec'd machine ([#5710](https://github.com/AztecProtocol/aztec-packages/issues/5710)) ([059e38e](https://github.com/AztecProtocol/aztec-packages/commit/059e38e3d319b84259bb1bf36fca6ed71425eb98)) +* **hotfix:** CI ignore git safe.directory checks ([#5659](https://github.com/AztecProtocol/aztec-packages/issues/5659)) ([9fc3fe3](https://github.com/AztecProtocol/aztec-packages/commit/9fc3fe3e5aa74e593eabb2fd1f358476f039e595)) +* Less earthly cache ([#5690](https://github.com/AztecProtocol/aztec-packages/issues/5690)) ([8190dc7](https://github.com/AztecProtocol/aztec-packages/commit/8190dc7826d480f44107456984f7f192358ba8da)) +* Make earthly more parallel ([#5747](https://github.com/AztecProtocol/aztec-packages/issues/5747)) ([9734455](https://github.com/AztecProtocol/aztec-packages/commit/9734455acd0d6e0cba44477f889ec8165e7f3003)) +* Primary_message typo in errors.rs ([#5646](https://github.com/AztecProtocol/aztec-packages/issues/5646)) ([1dfbe7b](https://github.com/AztecProtocol/aztec-packages/commit/1dfbe7bc3bf3c455d8fb6c8b5fe6a96c1edf7af9)) +* Pull noir ([#5699](https://github.com/AztecProtocol/aztec-packages/issues/5699)) ([bf35464](https://github.com/AztecProtocol/aztec-packages/commit/bf3546444272f36a3e3905246c49f2e5f65cff6e)) +* REDO dont error in bench summary ([#5695](https://github.com/AztecProtocol/aztec-packages/issues/5695)) ([8c1a7b9](https://github.com/AztecProtocol/aztec-packages/commit/8c1a7b976bcc63af63ddcc8cf4f89b338f17bdf8)) +* Running e2e tests as part of build, requires forcing ip4 (not ip6) when connecting to anvil ([#5744](https://github.com/AztecProtocol/aztec-packages/issues/5744)) ([66fc89f](https://github.com/AztecProtocol/aztec-packages/commit/66fc89f417d0582865acdb04a75258a4a449c8b6)) +* Simplify ECCVM prover constructor and add a TODO ([#5681](https://github.com/AztecProtocol/aztec-packages/issues/5681)) ([8c151ea](https://github.com/AztecProtocol/aztec-packages/commit/8c151eab1492dda901a1d6b691c9ca68960fd9e6)) +* Spot refcount ([#5746](https://github.com/AztecProtocol/aztec-packages/issues/5746)) ([9e18444](https://github.com/AztecProtocol/aztec-packages/commit/9e184448f218ab06247d8cbbadf755ad384bd40a)) +* Take a deep copy of circuit inputs for proving ([#5777](https://github.com/AztecProtocol/aztec-packages/issues/5777)) ([785591e](https://github.com/AztecProtocol/aztec-packages/commit/785591e0527beef7adf0f7a791618afff9df3705)) +* Temporarily disable the bench tests ([#5755](https://github.com/AztecProtocol/aztec-packages/issues/5755)) ([1d52ac5](https://github.com/AztecProtocol/aztec-packages/commit/1d52ac5c15524648094c23cf67ea0cfb921fe186)) +* Update commit for noir-gates-diff (https://github.com/noir-lang/noir/pull/4773) ([1eb288e](https://github.com/AztecProtocol/aztec-packages/commit/1eb288e9adc8b803e75ed80317c3e0979d0dfdee)) +* Use entrypoint instead of pay_init_fee ([#5623](https://github.com/AztecProtocol/aztec-packages/issues/5623)) ([62ac765](https://github.com/AztecProtocol/aztec-packages/commit/62ac765d192d499b7c8a8b1b4583c17fb95d00ac)) +* Watch less files. ([#5651](https://github.com/AztecProtocol/aztec-packages/issues/5651)) ([57a1d69](https://github.com/AztecProtocol/aztec-packages/commit/57a1d69f3fcade6f4536d007baad28e878242d59)) + + +### Miscellaneous + +* Add missing aztec-address tests ([#5674](https://github.com/AztecProtocol/aztec-packages/issues/5674)) ([58aefba](https://github.com/AztecProtocol/aztec-packages/commit/58aefbad0144b41619fa36a3714fa2a440945c74)) +* **avm:** Add a boolean to toggle proving in AVM unit tests ([#5667](https://github.com/AztecProtocol/aztec-packages/issues/5667)) ([ec122c9](https://github.com/AztecProtocol/aztec-packages/commit/ec122c9b9c1c63c72158c6956d8fdb2398faf96b)), closes [#5663](https://github.com/AztecProtocol/aztec-packages/issues/5663) +* **avm:** Hashing tests cleanup ([#5733](https://github.com/AztecProtocol/aztec-packages/issues/5733)) ([53d0102](https://github.com/AztecProtocol/aztec-packages/commit/53d010232600b736ac0f5116a3b7804f2d412dd0)) +* **avm:** Range checks negative tests ([#5770](https://github.com/AztecProtocol/aztec-packages/issues/5770)) ([2907142](https://github.com/AztecProtocol/aztec-packages/commit/29071423ba65774039e4e5c1f7ca67123a18f738)) +* **avm:** Split the negative test on range check for high 16-bit registers ([#5785](https://github.com/AztecProtocol/aztec-packages/issues/5785)) ([8ebbe57](https://github.com/AztecProtocol/aztec-packages/commit/8ebbe57953e35f81ca010cdd686fb43ddf0f20b2)) +* **avm:** Split up AVM test contract as it was growing too large ([#5702](https://github.com/AztecProtocol/aztec-packages/issues/5702)) ([5b8e812](https://github.com/AztecProtocol/aztec-packages/commit/5b8e812802457b429d173a5c4793ffa04faec1fa)) +* **aztec-nr:** Minor public interface changes ([#5776](https://github.com/AztecProtocol/aztec-packages/issues/5776)) ([91b8110](https://github.com/AztecProtocol/aztec-packages/commit/91b8110ab44979fe37fcc57824bdee845295ccb7)) +* **ci:** Break e2e-deploy into multiple test suites ([#5704](https://github.com/AztecProtocol/aztec-packages/issues/5704)) ([2522294](https://github.com/AztecProtocol/aztec-packages/commit/2522294d96e064b4531e05ae1b21eb4fa8f90125)) +* **ci:** Earthly in spot with persistent cache ([#5644](https://github.com/AztecProtocol/aztec-packages/issues/5644)) ([a39c2f6](https://github.com/AztecProtocol/aztec-packages/commit/a39c2f64565665260dbf8640478691dd5d47cee5)) +* **ci:** Hotfix AMI's, workflow to stop personal spot runners ([#5712](https://github.com/AztecProtocol/aztec-packages/issues/5712)) ([5f18139](https://github.com/AztecProtocol/aztec-packages/commit/5f1813947e05cc56553c8606a254f26d39ca6093)) +* **ci:** Only run ARM on master ([#5705](https://github.com/AztecProtocol/aztec-packages/issues/5705)) ([f77c142](https://github.com/AztecProtocol/aztec-packages/commit/f77c142b1634442434aa4631317186523d456a69)) +* **ci:** Use 128 cores for x86 and add timeouts ([#5665](https://github.com/AztecProtocol/aztec-packages/issues/5665)) ([0c5dc0a](https://github.com/AztecProtocol/aztec-packages/commit/0c5dc0a8d90c52c46f9802ec5fb93561d0551b6a)) +* Compute_note_hash_and_nullifier - improve error message ([#5671](https://github.com/AztecProtocol/aztec-packages/issues/5671)) ([8942d69](https://github.com/AztecProtocol/aztec-packages/commit/8942d69ab59f9ca7b33b72c91fb960c02afd66b0)) +* Create placeholder version of 0.26.0 docs (https://github.com/noir-lang/noir/pull/4782) ([1eb288e](https://github.com/AztecProtocol/aztec-packages/commit/1eb288e9adc8b803e75ed80317c3e0979d0dfdee)) +* **doc:** Fix broken docs links (https://github.com/noir-lang/noir/pull/4606) ([1eb288e](https://github.com/AztecProtocol/aztec-packages/commit/1eb288e9adc8b803e75ed80317c3e0979d0dfdee)) +* **docs:** Fix link in the Data Types page (https://github.com/noir-lang/noir/pull/4527) ([1eb288e](https://github.com/AztecProtocol/aztec-packages/commit/1eb288e9adc8b803e75ed80317c3e0979d0dfdee)) +* Don't strip bb wasm ([#5743](https://github.com/AztecProtocol/aztec-packages/issues/5743)) ([d4cb410](https://github.com/AztecProtocol/aztec-packages/commit/d4cb4108900f1fb6307de17be9ee3516d6023609)) +* Fix master after merge issue related to validate_trace renaming ([#5676](https://github.com/AztecProtocol/aztec-packages/issues/5676)) ([44e0d8a](https://github.com/AztecProtocol/aztec-packages/commit/44e0d8abd2104a9969d5750736e77fe9a8d4d621)) +* Fix max-block-number and auth e2e tests ([#5694](https://github.com/AztecProtocol/aztec-packages/issues/5694)) ([f1bf314](https://github.com/AztecProtocol/aztec-packages/commit/f1bf31431df68655fa5364c0504c2323ad660c22)) +* Op queue ([#5648](https://github.com/AztecProtocol/aztec-packages/issues/5648)) ([822c7e6](https://github.com/AztecProtocol/aztec-packages/commit/822c7e63e91cb30219a79513c05d84ee4f03d8fe)) +* **public:** Remove getNullifierMembershipWitness ([#5715](https://github.com/AztecProtocol/aztec-packages/issues/5715)) ([3be402c](https://github.com/AztecProtocol/aztec-packages/commit/3be402cca4fc1451a2b4c7560c346843eb8439cd)) +* Re-enable e2e fees tests ([#5784](https://github.com/AztecProtocol/aztec-packages/issues/5784)) ([102e8b8](https://github.com/AztecProtocol/aztec-packages/commit/102e8b89e91c324f945ab94357508c25eba4fa92)) +* Release Noir(0.27.0) (https://github.com/noir-lang/noir/pull/4632) ([1eb288e](https://github.com/AztecProtocol/aztec-packages/commit/1eb288e9adc8b803e75ed80317c3e0979d0dfdee)) +* Remove the old Value struct from the oracle docs (https://github.com/noir-lang/noir/pull/4738) ([1eb288e](https://github.com/AztecProtocol/aztec-packages/commit/1eb288e9adc8b803e75ed80317c3e0979d0dfdee)) +* Replace relative paths to noir-protocol-circuits ([fb2b298](https://github.com/AztecProtocol/aztec-packages/commit/fb2b298066bbf0fa15e5a39fa7e48cb288e50182)) +* Replace relative paths to noir-protocol-circuits ([e20920d](https://github.com/AztecProtocol/aztec-packages/commit/e20920d3b2f2acf4682eecc94a04e46fc50a8767)) +* Replace relative paths to noir-protocol-circuits ([6351dc5](https://github.com/AztecProtocol/aztec-packages/commit/6351dc52fe63200293aaf1749330a8f572356163)) +* Replace relative paths to noir-protocol-circuits ([fee13bf](https://github.com/AztecProtocol/aztec-packages/commit/fee13bf5869a03a84a05bb3166d0f5493c7056fd)) +* Replacing unsafe::zeroed() ([#5685](https://github.com/AztecProtocol/aztec-packages/issues/5685)) ([ea3884e](https://github.com/AztecProtocol/aztec-packages/commit/ea3884ec49e8a37d66b212551e1b78ab47a93e37)) +* Small logging changes ([#5654](https://github.com/AztecProtocol/aztec-packages/issues/5654)) ([25cc70d](https://github.com/AztecProtocol/aztec-packages/commit/25cc70de04342f89665883012b86f1c54c916c44)) +* Temporarily skip failing e2e fees test ([a3ac5ff](https://github.com/AztecProtocol/aztec-packages/commit/a3ac5ff251270f7a14d56e9b7846655dce716a44)) +* Testing that nargo fmt is idempotent (https://github.com/noir-lang/noir/pull/4765) ([825c455](https://github.com/AztecProtocol/aztec-packages/commit/825c455a62faeae5d148ce4f914efacb8f4c50fd)) +* TS hash wrappers cleanup ([#5691](https://github.com/AztecProtocol/aztec-packages/issues/5691)) ([7f8b09f](https://github.com/AztecProtocol/aztec-packages/commit/7f8b09fca6370b140870041a49692383a4db6551)) +* Turn ENABLE_GAS where it is needed ([#5730](https://github.com/AztecProtocol/aztec-packages/issues/5730)) ([30a2edd](https://github.com/AztecProtocol/aztec-packages/commit/30a2edd91cc46196c13fe421cdea2e03f30052fc)) +* Update noir gates diff ([#5658](https://github.com/AztecProtocol/aztec-packages/issues/5658)) ([9816c1a](https://github.com/AztecProtocol/aztec-packages/commit/9816c1adead8d3455c091664744f064bb0433ee7)) +* We can run 35 of our e2e tests just using jest. ([#5643](https://github.com/AztecProtocol/aztec-packages/issues/5643)) ([4fcaeae](https://github.com/AztecProtocol/aztec-packages/commit/4fcaeaea01acc42f87e6c6a5b0d229deaee2a063)) + + +### Documentation + +* Fix yp typo control-flow.md ([#5638](https://github.com/AztecProtocol/aztec-packages/issues/5638)) ([363d227](https://github.com/AztecProtocol/aztec-packages/commit/363d2275592f190d57501a25014bfe37ccad5e30)) + ## [0.34.0](https://github.com/AztecProtocol/aztec-packages/compare/aztec-packages-v0.33.0...aztec-packages-v0.34.0) (2024-04-10) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 50e57f5789f3..501ea2492a65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,9 +25,10 @@ When opening the pull request you will be presented with a template and a series If you're looking for a good place to start, look for issues labeled ["good first issue"](https://github.com/AztecProtocol/aztec-packages/labels/good%20first%20issue)! ## Pull request checklist: + - I've provided a paragraph or two giving a summary of the change in the description, including relevant motivation and context. - I've enabled auto-merge if the PR is ready to merge. -- I have updated the yellow paper when making changes to associated functionality (e.g. outward-facing spec changes). +- I have updated the protocol specs in the docs (aka the yellow paper) when making changes to associated functionality (e.g. outward-facing spec changes). - I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code. - Every change is related to the PR description. - I have [linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this pull request to relevant issues (if any exist). diff --git a/avm-transpiler/Cargo.lock b/avm-transpiler/Cargo.lock index ff3702060f53..6fc2aa934f5b 100644 --- a/avm-transpiler/Cargo.lock +++ b/avm-transpiler/Cargo.lock @@ -12,6 +12,7 @@ dependencies = [ "brillig", "flate2", "serde", + "serde-big-array", "thiserror", ] @@ -50,6 +51,7 @@ dependencies = [ "blake3", "k256", "keccak", + "num-bigint", "p256", "sha2", "sha3", @@ -184,7 +186,7 @@ dependencies = [ "ark-std", "derivative", "hashbrown 0.13.2", - "itertools", + "itertools 0.10.5", "num-traits", "zeroize", ] @@ -201,7 +203,7 @@ dependencies = [ "ark-std", "derivative", "digest", - "itertools", + "itertools 0.10.5", "num-bigint", "num-traits", "paste", @@ -290,6 +292,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -354,6 +365,33 @@ dependencies = [ "serde", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "bitmaps" version = "2.1.0" @@ -463,7 +501,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets", + "windows-targets 0.52.0", ] [[package]] @@ -586,6 +624,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-bigint" version = "0.4.9" @@ -685,6 +729,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "ecdsa" version = "0.14.8" @@ -723,6 +788,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ena" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +dependencies = [ + "log", +] + [[package]] name = "env_filter" version = "0.1.0" @@ -969,6 +1043,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" @@ -1017,12 +1100,63 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "lalrpop" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools 0.11.0", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata", +] + [[package]] name = "libc" version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.20" @@ -1055,6 +1189,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "noirc_abi" version = "0.27.0" @@ -1135,6 +1275,8 @@ dependencies = [ "chumsky", "fm", "iter-extended", + "lalrpop", + "lalrpop-util", "noirc_errors", "noirc_printable_type", "petgraph", @@ -1208,6 +1350,29 @@ dependencies = [ "sha2", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + [[package]] name = "paste" version = "1.0.14" @@ -1224,6 +1389,21 @@ dependencies = [ "indexmap 2.2.1", ] +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1252,6 +1432,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "proc-macro2" version = "1.0.78" @@ -1308,6 +1494,26 @@ dependencies = [ "rand_core", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.10.3" @@ -1397,6 +1603,12 @@ dependencies = [ "semver", ] +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + [[package]] name = "ryu" version = "1.0.16" @@ -1465,6 +1677,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sec1" version = "0.3.0" @@ -1494,6 +1712,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.196" @@ -1585,6 +1812,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "sized-chunks" version = "0.6.5" @@ -1629,6 +1862,19 @@ dependencies = [ "der", ] +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + [[package]] name = "strsim" version = "0.10.0" @@ -1663,6 +1909,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -1721,6 +1978,15 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "toml" version = "0.7.8" @@ -1810,6 +2076,12 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "utf8parse" version = "0.2.1" @@ -1929,7 +2201,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets", + "windows-targets 0.52.0", ] [[package]] @@ -1938,7 +2210,22 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -1947,51 +2234,93 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.0" diff --git a/avm-transpiler/src/opcodes.rs b/avm-transpiler/src/opcodes.rs index 38d26fa31f1c..ca41eba96740 100644 --- a/avm-transpiler/src/opcodes.rs +++ b/avm-transpiler/src/opcodes.rs @@ -1,5 +1,5 @@ /// All AVM opcodes -/// Keep updated with TS and yellow paper! +/// Keep updated with TS, cpp, and docs protocol specs! #[derive(PartialEq, Copy, Clone, Debug)] pub enum AvmOpcode { // Compute @@ -21,7 +21,6 @@ pub enum AvmOpcode { // Execution environment ADDRESS, STORAGEADDRESS, - ORIGIN, SENDER, PORTAL, FEEPERL1GAS, @@ -102,7 +101,6 @@ impl AvmOpcode { // Execution Environment AvmOpcode::ADDRESS => "ADDRESS", AvmOpcode::STORAGEADDRESS => "STORAGEADDRESS", - AvmOpcode::ORIGIN => "ORIGIN", AvmOpcode::SENDER => "SENDER", AvmOpcode::PORTAL => "PORTAL", AvmOpcode::FEEPERL1GAS => "FEEPERL1GAS", diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 8eca95879aec..fda785f1ff9c 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -1,8 +1,7 @@ use acvm::acir::brillig::Opcode as BrilligOpcode; -use acvm::acir::circuit::brillig::Brillig; use acvm::brillig_vm::brillig::{ - BinaryFieldOp, BinaryIntOp, BlackBoxOp, HeapArray, MemoryAddress, ValueOrArray, + BinaryFieldOp, BinaryIntOp, BlackBoxOp, HeapArray, HeapVector, MemoryAddress, ValueOrArray, }; use acvm::FieldElement; @@ -14,17 +13,17 @@ use crate::opcodes::AvmOpcode; use crate::utils::{dbg_print_avm_program, dbg_print_brillig_program}; /// Transpile a Brillig program to AVM bytecode -pub fn brillig_to_avm(brillig: &Brillig) -> Vec { - dbg_print_brillig_program(brillig); +pub fn brillig_to_avm(brillig_bytecode: &[BrilligOpcode]) -> Vec { + dbg_print_brillig_program(brillig_bytecode); let mut avm_instrs: Vec = Vec::new(); // Map Brillig pcs to AVM pcs // (some Brillig instructions map to >1 AVM instruction) - let brillig_pcs_to_avm_pcs = map_brillig_pcs_to_avm_pcs(avm_instrs.len(), brillig); + let brillig_pcs_to_avm_pcs = map_brillig_pcs_to_avm_pcs(avm_instrs.len(), brillig_bytecode); // Transpile a Brillig instruction to one or more AVM instructions - for brillig_instr in &brillig.bytecode { + for brillig_instr in brillig_bytecode { match brillig_instr { BrilligOpcode::BinaryFieldOp { destination, @@ -70,7 +69,11 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { lhs, rhs, } => { - assert!(is_integral_bit_size(*bit_size), "BinaryIntOp bit size should be integral: {:?}", brillig_instr); + assert!( + is_integral_bit_size(*bit_size), + "BinaryIntOp bit size should be integral: {:?}", + brillig_instr + ); let avm_opcode = match op { BinaryIntOp::Add => AvmOpcode::ADD, BinaryIntOp::Sub => AvmOpcode::SUB, @@ -102,20 +105,27 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { ], }); } - BrilligOpcode::CalldataCopy { destination_address, size, offset } => { + BrilligOpcode::CalldataCopy { + destination_address, + size, + offset, + } => { avm_instrs.push(AvmInstruction { opcode: AvmOpcode::CALLDATACOPY, indirect: Some(ALL_DIRECT), operands: vec![ AvmOperand::U32 { value: *offset as u32, // cdOffset (calldata offset) - }, AvmOperand::U32 { + }, + AvmOperand::U32 { value: *size as u32, - }, AvmOperand::U32 { + }, + AvmOperand::U32 { value: destination_address.to_usize() as u32, // dstOffset - }], - ..Default::default() - }); + }, + ], + ..Default::default() + }); } BrilligOpcode::Jump { location } => { let avm_loc = brillig_pcs_to_avm_pcs[*location]; @@ -146,14 +156,22 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { ..Default::default() }); } - BrilligOpcode::Const { destination, value, bit_size } => { + BrilligOpcode::Const { + destination, + value, + bit_size, + } => { handle_const(&mut avm_instrs, destination, value, bit_size); } BrilligOpcode::Mov { destination, source, } => { - avm_instrs.push(generate_mov_instruction(Some(ALL_DIRECT), source.to_usize() as u32, destination.to_usize() as u32)); + avm_instrs.push(generate_mov_instruction( + Some(ALL_DIRECT), + source.to_usize() as u32, + destination.to_usize() as u32, + )); } BrilligOpcode::ConditionalMov { source_a, @@ -165,10 +183,18 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { opcode: AvmOpcode::CMOV, indirect: Some(ALL_DIRECT), operands: vec![ - AvmOperand::U32 { value: source_a.to_usize() as u32 }, - AvmOperand::U32 { value: source_b.to_usize() as u32 }, - AvmOperand::U32 { value: condition.to_usize() as u32 }, - AvmOperand::U32 { value: destination.to_usize() as u32 }, + AvmOperand::U32 { + value: source_a.to_usize() as u32, + }, + AvmOperand::U32 { + value: source_b.to_usize() as u32, + }, + AvmOperand::U32 { + value: condition.to_usize() as u32, + }, + AvmOperand::U32 { + value: destination.to_usize() as u32, + }, ], ..Default::default() }); @@ -177,13 +203,21 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { destination, source_pointer, } => { - avm_instrs.push(generate_mov_instruction(Some(ZEROTH_OPERAND_INDIRECT), source_pointer.to_usize() as u32, destination.to_usize() as u32)); + avm_instrs.push(generate_mov_instruction( + Some(ZEROTH_OPERAND_INDIRECT), + source_pointer.to_usize() as u32, + destination.to_usize() as u32, + )); } BrilligOpcode::Store { destination_pointer, source, } => { - avm_instrs.push(generate_mov_instruction(Some(FIRST_OPERAND_INDIRECT), source.to_usize() as u32, destination_pointer.to_usize() as u32)); + avm_instrs.push(generate_mov_instruction( + Some(FIRST_OPERAND_INDIRECT), + source.to_usize() as u32, + destination_pointer.to_usize() as u32, + )); } BrilligOpcode::Call { location } => { let avm_loc = brillig_pcs_to_avm_pcs[*location]; @@ -199,38 +233,65 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { opcode: AvmOpcode::INTERNALRETURN, ..Default::default() }), - BrilligOpcode::Stop { return_data_offset, return_data_size } => { + BrilligOpcode::Stop { + return_data_offset, + return_data_size, + } => { avm_instrs.push(AvmInstruction { opcode: AvmOpcode::RETURN, indirect: Some(ALL_DIRECT), operands: vec![ - AvmOperand::U32 { value: *return_data_offset as u32 }, - AvmOperand::U32 { value: *return_data_size as u32 }, + AvmOperand::U32 { + value: *return_data_offset as u32, + }, + AvmOperand::U32 { + value: *return_data_size as u32, + }, ], ..Default::default() }); } - BrilligOpcode::Trap { /*return_data_offset, return_data_size*/ } => { - // TODO(https://github.com/noir-lang/noir/issues/3113): Trap should support return data + BrilligOpcode::Trap { + revert_data_offset, + revert_data_size, + } => { avm_instrs.push(AvmInstruction { opcode: AvmOpcode::REVERT, indirect: Some(ALL_DIRECT), operands: vec![ - //AvmOperand::U32 { value: *return_data_offset as u32}, - //AvmOperand::U32 { value: *return_data_size as u32}, - AvmOperand::U32 { value: 0 }, - AvmOperand::U32 { value: 0 }, + AvmOperand::U32 { + value: *revert_data_offset as u32, + }, + AvmOperand::U32 { + value: *revert_data_size as u32, + }, ], ..Default::default() }); - }, - BrilligOpcode::Cast { destination, source, bit_size } => { - avm_instrs.push(generate_cast_instruction(source.to_usize() as u32, destination.to_usize() as u32, tag_from_bit_size(*bit_size))); } - BrilligOpcode::ForeignCall { function, destinations, inputs, destination_value_types:_, input_value_types:_ } => { + BrilligOpcode::Cast { + destination, + source, + bit_size, + } => { + avm_instrs.push(generate_cast_instruction( + source.to_usize() as u32, + destination.to_usize() as u32, + tag_from_bit_size(*bit_size), + )); + } + BrilligOpcode::ForeignCall { + function, + destinations, + inputs, + destination_value_types: _, + input_value_types: _, + } => { handle_foreign_call(&mut avm_instrs, function, destinations, inputs); - }, - BrilligOpcode::BlackBox(operation) => handle_black_box_function(&mut avm_instrs, operation), + } + BrilligOpcode::BlackBox(operation) => { + handle_black_box_function(&mut avm_instrs, operation) + } _ => panic!( "Transpiler doesn't know how to process {:?} brillig instruction", brillig_instr @@ -318,16 +379,16 @@ fn handle_external_call( inputs: &Vec, opcode: AvmOpcode, ) { - if destinations.len() != 2 || inputs.len() != 4 { + if destinations.len() != 2 || inputs.len() != 5 { panic!( - "Transpiler expects ForeignCall (Static)Call to have 2 destinations and 4 inputs, got {} and {}. + "Transpiler expects ForeignCall (Static)Call to have 2 destinations and 5 inputs, got {} and {}. Make sure your call instructions's input/return arrays have static length (`[Field; ]`)!", destinations.len(), inputs.len() ); } - let gas_offset_maybe = inputs[0]; - let gas_offset = match gas_offset_maybe { + let gas = inputs[0]; + let gas_offset = match gas { ValueOrArray::HeapArray(HeapArray { pointer, size }) => { assert!(size == 3, "Call instruction's gas input should be a HeapArray of size 3 (`[l1Gas, l2Gas, daGas]`)"); pointer.0 as u32 @@ -339,13 +400,16 @@ fn handle_external_call( ValueOrArray::MemoryAddress(offset) => offset.to_usize() as u32, _ => panic!("Call instruction's target address input should be a basic MemoryAddress",), }; - let args_offset_maybe = inputs[2]; - let (args_offset, args_size) = match args_offset_maybe { - ValueOrArray::HeapArray(HeapArray { pointer, size }) => (pointer.0 as u32, size as u32), - ValueOrArray::HeapVector(_) => panic!("Call instruction's args must be a HeapArray, not a HeapVector. Make sure you are explicitly defining its size (`[arg0, arg1, ... argN]`)!"), - _ => panic!("Call instruction's args input should be a HeapArray input"), + // The args are a slice, and this is represented as a (Field, HeapVector). + // The field is the length (memory address) and the HeapVector has the data and length again. + // This is an ACIR internal representation detail that leaks to the SSA. + // Observe that below, we use `inputs[3]` and therefore skip the length field. + let args = inputs[3]; + let (args_offset, args_size_offset) = match args { + ValueOrArray::HeapVector(HeapVector { pointer, size }) => (pointer.0 as u32, size.0 as u32), + _ => panic!("Call instruction's args input should be a HeapVector input"), }; - let temporary_function_selector_offset = match &inputs[3] { + let temporary_function_selector_offset = match &inputs[4] { ValueOrArray::MemoryAddress(offset) => offset.to_usize() as u32, _ => panic!( "Call instruction's temporary function selector input should be a basic MemoryAddress", @@ -364,14 +428,23 @@ fn handle_external_call( }; avm_instrs.push(AvmInstruction { opcode: opcode, - indirect: Some(0b01101), // (left to right) selector direct, ret offset INDIRECT, args offset INDIRECT, address offset direct, gas offset INDIRECT + // (left to right) + // * selector direct + // * ret offset INDIRECT + // * arg size offset direct + // * args offset INDIRECT + // * address offset direct + // * gas offset INDIRECT + indirect: Some(0b010101), operands: vec![ AvmOperand::U32 { value: gas_offset }, AvmOperand::U32 { value: address_offset, }, AvmOperand::U32 { value: args_offset }, - AvmOperand::U32 { value: args_size }, + AvmOperand::U32 { + value: args_size_offset, + }, AvmOperand::U32 { value: ret_offset }, AvmOperand::U32 { value: ret_size }, AvmOperand::U32 { @@ -670,7 +743,6 @@ fn handle_getter_instruction( let opcode = match function { "avmOpcodeAddress" => AvmOpcode::ADDRESS, "avmOpcodeStorageAddress" => AvmOpcode::STORAGEADDRESS, - "avmOpcodeOrigin" => AvmOpcode::ORIGIN, "avmOpcodeSender" => AvmOpcode::SENDER, "avmOpcodePortal" => AvmOpcode::PORTAL, "avmOpcodeFeePerL1Gas" => AvmOpcode::FEEPERL1GAS, @@ -1017,12 +1089,15 @@ fn handle_storage_read( /// brillig: the Brillig program /// returns: an array where each index is a Brillig pc, /// and each value is the corresponding AVM pc. -fn map_brillig_pcs_to_avm_pcs(initial_offset: usize, brillig: &Brillig) -> Vec { - let mut pc_map = vec![0; brillig.bytecode.len()]; +fn map_brillig_pcs_to_avm_pcs( + initial_offset: usize, + brillig_bytecode: &[BrilligOpcode], +) -> Vec { + let mut pc_map = vec![0; brillig_bytecode.len()]; pc_map[0] = initial_offset; - for i in 0..brillig.bytecode.len() - 1 { - let num_avm_instrs_for_this_brillig_instr = match &brillig.bytecode[i] { + for i in 0..brillig_bytecode.len() - 1 { + let num_avm_instrs_for_this_brillig_instr = match &brillig_bytecode[i] { BrilligOpcode::Const { bit_size: 254, .. } => 2, _ => 1, }; diff --git a/avm-transpiler/src/transpile_contract.rs b/avm-transpiler/src/transpile_contract.rs index 537dfb34bb3d..e28b20aa4a33 100644 --- a/avm-transpiler/src/transpile_contract.rs +++ b/avm-transpiler/src/transpile_contract.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use acvm::acir::circuit::Program; use crate::transpile::brillig_to_avm; -use crate::utils::extract_brillig_from_acir; +use crate::utils::extract_brillig_from_acir_program; /// Representation of a contract with some transpiled functions #[derive(Debug, Serialize, Deserialize)] @@ -88,10 +88,10 @@ impl From for TranspiledContract { ); // Extract Brillig Opcodes from acir let acir_program = function.bytecode; - let brillig = extract_brillig_from_acir(&acir_program.functions[0].opcodes); + let brillig_bytecode = extract_brillig_from_acir_program(&acir_program); // Transpile to AVM - let avm_bytecode = brillig_to_avm(brillig); + let avm_bytecode = brillig_to_avm(brillig_bytecode); // Push modified function entry to ABI functions.push(AvmOrAcirContractFunction::Avm(AvmContractFunction { diff --git a/avm-transpiler/src/utils.rs b/avm-transpiler/src/utils.rs index 684dde7b6e4a..97667a386c06 100644 --- a/avm-transpiler/src/utils.rs +++ b/avm-transpiler/src/utils.rs @@ -1,33 +1,46 @@ use log::debug; -use acvm::acir::circuit::brillig::Brillig; -use acvm::acir::circuit::Opcode; +use acvm::acir::brillig::Opcode as BrilligOpcode; +use acvm::acir::circuit::{Opcode, Program}; use crate::instructions::AvmInstruction; -/// Extract the Brillig program from its ACIR wrapper instruction. -/// An Noir unconstrained function compiles to one ACIR instruction -/// wrapping a Brillig program. This function just extracts that Brillig -/// assuming the 0th ACIR opcode is the wrapper. -pub fn extract_brillig_from_acir(opcodes: &Vec) -> &Brillig { - if opcodes.len() != 1 { - panic!("An AVM program should be contained entirely in only a single ACIR opcode flagged as 'Brillig'"); - } - let opcode = &opcodes[0]; - match opcode { - Opcode::Brillig(brillig) => brillig, +/// Extract the Brillig program from its `Program` wrapper. +/// Noir entry point unconstrained functions are compiled to their own list contained +/// as part of a full program. Function calls are then accessed through a function +/// pointer opcode in ACIR that fetches those unconstrained functions from the main list. +/// This function just extracts Brillig bytecode, with the assumption that the +/// 0th unconstrained function in the full `Program` structure. +pub fn extract_brillig_from_acir_program(program: &Program) -> &[BrilligOpcode] { + assert_eq!( + program.functions.len(), + 1, + "An AVM program should have only a single ACIR function flagged as 'BrilligCall'" + ); + let opcodes = &program.functions[0].opcodes; + assert_eq!( + opcodes.len(), + 1, + "An AVM program should have only a single ACIR function flagged as 'BrilligCall'" + ); + match opcodes[0] { + Opcode::BrilligCall { .. } => {} _ => panic!("Tried to extract a Brillig program from its ACIR wrapper opcode, but the opcode doesn't contain Brillig!"), } + assert_eq!( + program.unconstrained_functions.len(), + 1, + "An AVM program should be contained entirely in only a single `Brillig` function" + ); + &program.unconstrained_functions[0].bytecode } /// Print inputs, outputs, and instructions in a Brillig program -pub fn dbg_print_brillig_program(brillig: &Brillig) { +pub fn dbg_print_brillig_program(brillig_bytecode: &[BrilligOpcode]) { debug!("Printing Brillig program..."); - debug!("\tInputs: {:?}", brillig.inputs); - for (i, instruction) in brillig.bytecode.iter().enumerate() { + for (i, instruction) in brillig_bytecode.iter().enumerate() { debug!("\tPC:{0} {1:?}", i, instruction); } - debug!("\tOutputs: {:?}", brillig.outputs); } /// Print each instruction in an AVM program diff --git a/barretenberg/.gitrepo b/barretenberg/.gitrepo index 063f1708538e..107719b5a24f 100644 --- a/barretenberg/.gitrepo +++ b/barretenberg/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AztecProtocol/barretenberg branch = master - commit = eca2641c091cb50d32b41acb02e0826d3c71ca96 - parent = 66fc89f417d0582865acdb04a75258a4a449c8b6 + commit = ed310b6d7e43b47913afacb717513cd4ff2d57dd + parent = 3fb94c0cd5ffba20a99b97c0088ae5ef357c205d method = merge cmdver = 0.4.6 diff --git a/barretenberg/CHANGELOG.md b/barretenberg/CHANGELOG.md index 1d86094065ac..d37b74ee13c1 100644 --- a/barretenberg/CHANGELOG.md +++ b/barretenberg/CHANGELOG.md @@ -1,5 +1,56 @@ # Changelog +## [0.35.1](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg-v0.35.0...barretenberg-v0.35.1) (2024-04-16) + + +### Miscellaneous + +* **barretenberg:** Synchronize aztec-packages versions + +## [0.35.0](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg-v0.34.0...barretenberg-v0.35.0) (2024-04-16) + + +### ⚠ BREAKING CHANGES + +* Use fixed size arrays in black box functions where sizes are known ([#5620](https://github.com/AztecProtocol/aztec-packages/issues/5620)) +* trap with revert data ([#5732](https://github.com/AztecProtocol/aztec-packages/issues/5732)) +* **acir:** BrilligCall opcode ([#5709](https://github.com/AztecProtocol/aztec-packages/issues/5709)) + +### Features + +* **acir:** BrilligCall opcode ([#5709](https://github.com/AztecProtocol/aztec-packages/issues/5709)) ([f06f64c](https://github.com/AztecProtocol/aztec-packages/commit/f06f64c451333d36eb05951202d69ee85cca8851)) +* **avm:** CMOV opcode ([#5575](https://github.com/AztecProtocol/aztec-packages/issues/5575)) ([19dbe46](https://github.com/AztecProtocol/aztec-packages/commit/19dbe46bce95221bf2e68c9361618998a6bdc64f)), closes [#5557](https://github.com/AztecProtocol/aztec-packages/issues/5557) +* **avm:** Enable contract testing with bb binary ([#5584](https://github.com/AztecProtocol/aztec-packages/issues/5584)) ([d007d79](https://github.com/AztecProtocol/aztec-packages/commit/d007d79c7014261d9c663e28c948600d92e85759)) +* **avm:** Enable range check on the ALU registers ([#5696](https://github.com/AztecProtocol/aztec-packages/issues/5696)) ([202fc1b](https://github.com/AztecProtocol/aztec-packages/commit/202fc1b750e83f91c32b128b981db1c5c92ef3f2)) +* Changing finite field arithmetic in wasm to 29 bits for multiplications ([#5435](https://github.com/AztecProtocol/aztec-packages/issues/5435)) ([b2d9b9d](https://github.com/AztecProtocol/aztec-packages/commit/b2d9b9d5f1764b159e081b3cc9806ee83fdf341f)) +* **ci:** Turn on new CI as mandatory ([#5761](https://github.com/AztecProtocol/aztec-packages/issues/5761)) ([bebed32](https://github.com/AztecProtocol/aztec-packages/commit/bebed32272e0974de21b5c7d21344d3cf1597a24)) +* Export poseidon2_permutation and add to foundation/crypto ([#5706](https://github.com/AztecProtocol/aztec-packages/issues/5706)) ([6b91e27](https://github.com/AztecProtocol/aztec-packages/commit/6b91e2776de8fd5b1f489b5cfeee83c7e0996c2e)) +* LT/LTE for AVM ([#5559](https://github.com/AztecProtocol/aztec-packages/issues/5559)) ([350abeb](https://github.com/AztecProtocol/aztec-packages/commit/350abeb4c88d7e7878abc32e9263c558633f0df9)) +* Trap with revert data ([#5732](https://github.com/AztecProtocol/aztec-packages/issues/5732)) ([f849575](https://github.com/AztecProtocol/aztec-packages/commit/f84957584ff76c22c069903f7648735a0be91d7f)) +* Use fixed size arrays in black box functions where sizes are known ([#5620](https://github.com/AztecProtocol/aztec-packages/issues/5620)) ([f50b180](https://github.com/AztecProtocol/aztec-packages/commit/f50b180379ac90d782aba3472708f8cef122c25b)) + + +### Bug Fixes + +* "feat: Changing finite field arithmetic in wasm to 29 bits for multiplications" ([#5779](https://github.com/AztecProtocol/aztec-packages/issues/5779)) ([bcfee97](https://github.com/AztecProtocol/aztec-packages/commit/bcfee97da99c654f8641ab8099bbbe5d58e2a5c7)) +* Avoid get row in databus ([#5742](https://github.com/AztecProtocol/aztec-packages/issues/5742)) ([d67b6c8](https://github.com/AztecProtocol/aztec-packages/commit/d67b6c8bb703d856c0d95d4d47cc6de93467e9ab)) +* **ci:** Bigger cache disk, cache+prune docker images, disable ClientIvcTests.Full ([#5729](https://github.com/AztecProtocol/aztec-packages/issues/5729)) ([5dcbd75](https://github.com/AztecProtocol/aztec-packages/commit/5dcbd75c0795640d48592efbd750cd22b5e5ddd5)) +* Disable flakey vanilla recursion test ([#5672](https://github.com/AztecProtocol/aztec-packages/issues/5672)) ([f84f7b6](https://github.com/AztecProtocol/aztec-packages/commit/f84f7b68f6c8072480127a065def1c4453e55877)) +* Less earthly cache ([#5690](https://github.com/AztecProtocol/aztec-packages/issues/5690)) ([8190dc7](https://github.com/AztecProtocol/aztec-packages/commit/8190dc7826d480f44107456984f7f192358ba8da)) +* Make earthly more parallel ([#5747](https://github.com/AztecProtocol/aztec-packages/issues/5747)) ([9734455](https://github.com/AztecProtocol/aztec-packages/commit/9734455acd0d6e0cba44477f889ec8165e7f3003)) +* Simplify ECCVM prover constructor and add a TODO ([#5681](https://github.com/AztecProtocol/aztec-packages/issues/5681)) ([8c151ea](https://github.com/AztecProtocol/aztec-packages/commit/8c151eab1492dda901a1d6b691c9ca68960fd9e6)) + + +### Miscellaneous + +* **avm:** Add a boolean to toggle proving in AVM unit tests ([#5667](https://github.com/AztecProtocol/aztec-packages/issues/5667)) ([ec122c9](https://github.com/AztecProtocol/aztec-packages/commit/ec122c9b9c1c63c72158c6956d8fdb2398faf96b)), closes [#5663](https://github.com/AztecProtocol/aztec-packages/issues/5663) +* **avm:** Range checks negative tests ([#5770](https://github.com/AztecProtocol/aztec-packages/issues/5770)) ([2907142](https://github.com/AztecProtocol/aztec-packages/commit/29071423ba65774039e4e5c1f7ca67123a18f738)) +* **avm:** Split the negative test on range check for high 16-bit registers ([#5785](https://github.com/AztecProtocol/aztec-packages/issues/5785)) ([8ebbe57](https://github.com/AztecProtocol/aztec-packages/commit/8ebbe57953e35f81ca010cdd686fb43ddf0f20b2)) +* **ci:** Use 128 cores for x86 and add timeouts ([#5665](https://github.com/AztecProtocol/aztec-packages/issues/5665)) ([0c5dc0a](https://github.com/AztecProtocol/aztec-packages/commit/0c5dc0a8d90c52c46f9802ec5fb93561d0551b6a)) +* Don't strip bb wasm ([#5743](https://github.com/AztecProtocol/aztec-packages/issues/5743)) ([d4cb410](https://github.com/AztecProtocol/aztec-packages/commit/d4cb4108900f1fb6307de17be9ee3516d6023609)) +* Fix master after merge issue related to validate_trace renaming ([#5676](https://github.com/AztecProtocol/aztec-packages/issues/5676)) ([44e0d8a](https://github.com/AztecProtocol/aztec-packages/commit/44e0d8abd2104a9969d5750736e77fe9a8d4d621)) +* Op queue ([#5648](https://github.com/AztecProtocol/aztec-packages/issues/5648)) ([822c7e6](https://github.com/AztecProtocol/aztec-packages/commit/822c7e63e91cb30219a79513c05d84ee4f03d8fe)) + ## [0.34.0](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg-v0.33.0...barretenberg-v0.34.0) (2024-04-10) diff --git a/barretenberg/cpp/CMakeLists.txt b/barretenberg/cpp/CMakeLists.txt index fec9ce4240e4..6a6f31707573 100644 --- a/barretenberg/cpp/CMakeLists.txt +++ b/barretenberg/cpp/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.24 FATAL_ERROR) project( Barretenberg DESCRIPTION "BN254 elliptic curve library, and PLONK SNARK prover" - VERSION 0.34.0 # x-release-please-version + VERSION 0.35.1 # x-release-please-version LANGUAGES CXX C ) # Insert version into `bb` config file diff --git a/barretenberg/cpp/Earthfile b/barretenberg/cpp/Earthfile index 3d1dbc3aece5..346d1be3d07c 100644 --- a/barretenberg/cpp/Earthfile +++ b/barretenberg/cpp/Earthfile @@ -117,7 +117,8 @@ preset-wasm-threads: FROM +source COPY +get-wasi-sdk-threads/wasi-sdk src/wasi-sdk RUN cmake --preset wasm-threads -Bbuild && cmake --build build --target barretenberg.wasm - RUN src/wasi-sdk/bin/llvm-strip ./build/bin/barretenberg.wasm + # TODO(https://github.com/AztecProtocol/barretenberg/issues/941) We currently do not strip barretenberg threaded wasm, for stack traces. + # RUN src/wasi-sdk/bin/llvm-strip ./build/bin/barretenberg.wasm SAVE ARTIFACT build/bin preset-gcc: @@ -187,6 +188,7 @@ bench-binaries: # Runs on the bench image, sent from the builder runner bench-ultra-honk: + BUILD +wasmtime # prefetch FROM +source COPY --dir +bench-binaries/* . # install SRS needed for proving @@ -198,6 +200,7 @@ bench-ultra-honk: RUN cd wasm && wasmtime run --env HARDWARE_CONCURRENCY=16 -Wthreads=y -Sthreads=y --dir=".." ./bin/ultra_honk_bench --benchmark_filter="construct_proof_ultrahonk_power_of_2/20$" bench-client-ivc: + BUILD +wasmtime # prefetch FROM +source COPY --dir +bench-binaries/* . # install SRS needed for proving @@ -232,9 +235,15 @@ test-clang-format: RUN ./format.sh check test: + ARG hardware_concurrency="" + BUILD +test-clang-format + BUILD ./srs_db/+build # prefetch FROM +source COPY --dir +test-binaries/build build - BUILD +test-clang-format FROM +preset-release-assert-test COPY --dir ./srs_db/+build/. srs_db + # limit hardware concurrency, if provided + IF [ "$HARDWARE_CONCURRENCY" != "" ] + ENV HARDWARE_CONCURRENCY=$hardware_concurrency + END RUN cd build && GTEST_COLOR=1 ctest -j$(nproc) --output-on-failure diff --git a/barretenberg/cpp/scripts/strip-wasm.sh b/barretenberg/cpp/scripts/strip-wasm.sh index 5f43b82cc896..18e3cf78d02b 100755 --- a/barretenberg/cpp/scripts/strip-wasm.sh +++ b/barretenberg/cpp/scripts/strip-wasm.sh @@ -1,3 +1,4 @@ #!/bin/sh ./src/wasi-sdk-20.0/bin/llvm-strip ./build-wasm/bin/barretenberg.wasm -./src/wasi-sdk-20.0/bin/llvm-strip ./build-wasm-threads/bin/barretenberg.wasm +# TODO(https://github.com/AztecProtocol/barretenberg/issues/941) We currently do not strip barretenberg threaded wasm, for stack traces. +# ./src/wasi-sdk-20.0/bin/llvm-strip ./build-wasm-threads/bin/barretenberg.wasm diff --git a/barretenberg/cpp/src/barretenberg/bb/main.cpp b/barretenberg/cpp/src/barretenberg/bb/main.cpp index 8c1eed36e37c..83c019a34013 100644 --- a/barretenberg/cpp/src/barretenberg/bb/main.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/main.cpp @@ -492,7 +492,7 @@ void acvm_info(const std::string& output_path) const char* jsonData = R"({ "language": { "name" : "PLONK-CSAT", - "width" : 3 + "width" : 4 } })"; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 3bafc86f92bd..5ece3c031d48 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -13,9 +13,12 @@ template void build_constraints(Builder& builder, AcirFormat const& constraint_system, bool has_valid_witness_assignments) { // Add arithmetic gates - for (const auto& constraint : constraint_system.constraints) { + for (const auto& constraint : constraint_system.poly_triple_constraints) { builder.create_poly_gate(constraint); } + for (const auto& constraint : constraint_system.quad_constraints) { + builder.create_big_mul_gate(constraint); + } // Add logic constraint for (const auto& constraint : constraint_system.logic_constraints) { diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index c91d98c6fcdd..ec82362e2d8b 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -59,7 +59,9 @@ struct AcirFormat { // This could be a large vector so use slab allocator, we don't expect the blackbox implementations to be so large. std::vector, ContainerSlabAllocator>> - constraints; + poly_triple_constraints; + std::vector, ContainerSlabAllocator>> + quad_constraints; std::vector block_constraints; // For serialization, update with any new fields @@ -82,7 +84,7 @@ struct AcirFormat { fixed_base_scalar_mul_constraints, ec_add_constraints, recursion_constraints, - constraints, + poly_triple_constraints, block_constraints, bigint_from_le_bytes_constraints, bigint_to_le_bytes_constraints, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index 5d2fae4d9880..c7d44e319413 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -53,7 +53,8 @@ TEST_F(AcirFormatTests, TestASingleConstraintNoPubInputs) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = { constraint }, + .poly_triple_constraints = { constraint }, + .quad_constraints = {}, .block_constraints = {}, }; @@ -168,7 +169,8 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = { expr_a, expr_b, expr_c, expr_d }, + .poly_triple_constraints = { expr_a, expr_b, expr_c, expr_d }, + .quad_constraints = {}, .block_constraints = {} }; uint256_t inverse_of_five = fr(5).invert(); @@ -196,7 +198,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass) }); } - std::vector signature(64); + std::array signature; for (uint32_t i = 0, value = 12; i < 64; i++, value++) { signature[i] = value; range_constraints.push_back(RangeConstraint{ @@ -235,7 +237,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = { poly_triple{ + .poly_triple_constraints = { poly_triple{ .a = schnorr_constraint.result, .b = schnorr_constraint.result, .c = schnorr_constraint.result, @@ -245,6 +247,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass) .q_o = 1, .q_c = fr::neg_one(), } }, + .quad_constraints = {}, .block_constraints = {} }; std::string message_string = "tenletters"; @@ -289,7 +292,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange) }); } - std::vector signature(64); + std::array signature; for (uint32_t i = 0, value = 12; i < 64; i++, value++) { signature[i] = value; range_constraints.push_back(RangeConstraint{ @@ -329,7 +332,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = { poly_triple{ + .poly_triple_constraints = { poly_triple{ .a = schnorr_constraint.result, .b = schnorr_constraint.result, .c = schnorr_constraint.result, @@ -339,6 +342,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange) .q_o = 1, .q_c = fr::neg_one(), } }, + .quad_constraints = {}, .block_constraints = {}, }; @@ -442,7 +446,8 @@ TEST_F(AcirFormatTests, TestVarKeccak) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = { dummy }, + .poly_triple_constraints = { dummy }, + .quad_constraints = {}, .block_constraints = {}, }; @@ -488,7 +493,8 @@ TEST_F(AcirFormatTests, TestKeccakPermutation) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {} }; WitnessVector witness{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp index 0034d4cae832..778363f3258c 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp @@ -21,7 +21,7 @@ #include namespace acir_format { - +using mul_quad = mul_quad_; /** * @brief Construct a poly_tuple for a standard width-3 arithmetic gate from its acir representation * @@ -90,7 +90,16 @@ poly_triple serialize_arithmetic_gate(Program::Expression const& arg) pt.q_o = selector_value; c_set = true; } else { - throw_or_abort("Cannot assign linear term to a constraint of width 3"); + return poly_triple{ + .a = 0, + .b = 0, + .c = 0, + .q_m = 0, + .q_l = 0, + .q_r = 0, + .q_o = 0, + .q_c = 0, + }; } } @@ -98,10 +107,93 @@ poly_triple serialize_arithmetic_gate(Program::Expression const& arg) pt.q_c = uint256_t(arg.q_c); return pt; } +mul_quad serialize_mul_quad_gate(Program::Expression const& arg) +{ + // TODO(https://github.com/AztecProtocol/barretenberg/issues/816): The initialization of the witness indices a,b,c + // to 0 is implicitly assuming that (builder.zero_idx == 0) which is no longer the case. Now, witness idx 0 in + // general will correspond to some non-zero value and some witnesses which are not explicitly set below will be + // erroneously populated with this value. This does not cause failures however because the corresponding selector + // will indeed be 0 so the gate will be satisfied. Still, its a bad idea to have erroneous wire values + // even if they dont break the relation. They'll still add cost in commitments, for example. + mul_quad quad{ .a = 0, + .b = 0, + .c = 0, + .d = 0, + .mul_scaling = 0, + .a_scaling = 0, + .b_scaling = 0, + .c_scaling = 0, + .d_scaling = 0, + .const_scaling = 0 }; + + // Flags indicating whether each witness index for the present mul_quad has been set + bool a_set = false; + bool b_set = false; + bool c_set = false; + bool d_set = false; + ASSERT(arg.mul_terms.size() <= 1); // We can only accommodate 1 quadratic term + // Note: mul_terms are tuples of the form {selector_value, witness_idx_1, witness_idx_2} + if (!arg.mul_terms.empty()) { + const auto& mul_term = arg.mul_terms[0]; + quad.mul_scaling = uint256_t(std::get<0>(mul_term)); + quad.a = std::get<1>(mul_term).value; + quad.b = std::get<2>(mul_term).value; + a_set = true; + b_set = true; + } + // If necessary, set values for linears terms q_l * w_l, q_r * w_r and q_o * w_o + ASSERT(arg.linear_combinations.size() <= 4); // We can only accommodate 4 linear terms + for (const auto& linear_term : arg.linear_combinations) { + bb::fr selector_value(uint256_t(std::get<0>(linear_term))); + uint32_t witness_idx = std::get<1>(linear_term).value; + + // If the witness index has not yet been set or if the corresponding linear term is active, set the witness + // index and the corresponding selector value. + // TODO(https://github.com/AztecProtocol/barretenberg/issues/816): May need to adjust the quad.a == witness_idx + // check (and the others like it) since we initialize a,b,c with 0 but 0 is a valid witness index once the + // +1 offset is removed from noir. + if (!a_set || quad.a == witness_idx) { + quad.a = witness_idx; + quad.a_scaling = selector_value; + a_set = true; + } else if (!b_set || quad.b == witness_idx) { + quad.b = witness_idx; + quad.b_scaling = selector_value; + b_set = true; + } else if (!c_set || quad.c == witness_idx) { + quad.c = witness_idx; + quad.c_scaling = selector_value; + c_set = true; + } else if (!d_set || quad.d == witness_idx) { + quad.d = witness_idx; + quad.d_scaling = selector_value; + d_set = true; + } else { + throw_or_abort("Cannot assign linear term to a constraint of width 4"); + } + } + + // Set constant value q_c + quad.const_scaling = uint256_t(arg.q_c); + return quad; +} void handle_arithmetic(Program::Opcode::AssertZero const& arg, AcirFormat& af) { - af.constraints.push_back(serialize_arithmetic_gate(arg.value)); + if (arg.value.linear_combinations.size() <= 3) { + poly_triple pt = serialize_arithmetic_gate(arg.value); + // Even if the number of linear terms is less than 3, we might not be able to fit it into a width-3 arithmetic + // gate. This is the case if the linear terms are all disctinct witness from the multiplication term. In that + // case, the serialize_arithmetic_gate() function will return a poly_triple with all 0's, and we use a width-4 + // gate instead. We could probably always use a width-4 gate in fact. + if (pt == poly_triple{ 0, 0, 0, 0, 0, 0, 0, 0 }) { + af.quad_constraints.push_back(serialize_mul_quad_gate(arg.value)); + } else { + af.poly_triple_constraints.push_back(pt); + } + } else { + af.quad_constraints.push_back(serialize_mul_quad_gate(arg.value)); + } } void handle_blackbox_func_call(Program::Opcode::BlackBoxFuncCall const& arg, AcirFormat& af) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp index 90d61c52cd51..584f7ef62a56 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp @@ -190,7 +190,8 @@ TEST_F(BigIntTests, TestBigIntConstraintMultiple) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; apply_constraints(constraint_system, contraints); @@ -257,7 +258,8 @@ TEST_F(BigIntTests, TestBigIntConstraintSimple) .bigint_from_le_bytes_constraints = { from_le_bytes_constraint_bigint1 }, .bigint_to_le_bytes_constraints = { result2_to_le_bytes }, .bigint_operations = { add_constraint }, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; @@ -309,7 +311,8 @@ TEST_F(BigIntTests, TestBigIntConstraintReuse) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; apply_constraints(constraint_system, contraints); @@ -365,7 +368,8 @@ TEST_F(BigIntTests, TestBigIntConstraintReuse2) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; apply_constraints(constraint_system, contraints); @@ -442,7 +446,8 @@ TEST_F(BigIntTests, TestBigIntDIV) .bigint_from_le_bytes_constraints = { from_le_bytes_constraint_bigint1, from_le_bytes_constraint_bigint2 }, .bigint_to_le_bytes_constraints = { result3_to_le_bytes }, .bigint_operations = { div_constraint }, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp index a4bf7983e473..cf55b5fb7e71 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/blake2s_constraint.hpp @@ -17,7 +17,7 @@ struct Blake2sInput { struct Blake2sConstraint { std::vector inputs; - std::vector result; + std::array result; // For serialization, update with any new fields MSGPACK_FIELDS(inputs, result); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/blake3_constraint.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/blake3_constraint.hpp index 2fe421fb16ce..c2d1ecafde79 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/blake3_constraint.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/blake3_constraint.hpp @@ -17,7 +17,7 @@ struct Blake3Input { struct Blake3Constraint { std::vector inputs; - std::vector result; + std::array result; // For serialization, update with any new fields MSGPACK_FIELDS(inputs, result); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index 88d54261ea8f..20f9e8072bba 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -132,7 +132,8 @@ TEST_F(UltraPlonkRAM, TestBlockConstraint) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = { block }, }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp index 479d42a2f3c8..92c76e3d7a37 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp @@ -72,7 +72,8 @@ TEST_F(EcOperations, TestECOperations) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp index 863c4f7b0670..c402c94a954a 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp @@ -5,44 +5,6 @@ namespace acir_format { using namespace bb::plonk; -template -crypto::ecdsa_signature ecdsa_convert_signature(Builder& builder, std::vector signature) -{ - - crypto::ecdsa_signature signature_cr; - - // Get the witness assignment for each witness index - // Write the witness assignment to the byte_array - - for (unsigned int i = 0; i < 32; i++) { - auto witness_index = signature[i]; - - std::vector fr_bytes(sizeof(fr)); - - fr value = builder.get_variable(witness_index); - - fr::serialize_to_buffer(value, &fr_bytes[0]); - - signature_cr.r[i] = fr_bytes.back(); - } - - for (unsigned int i = 32; i < 64; i++) { - auto witness_index = signature[i]; - - std::vector fr_bytes(sizeof(fr)); - - fr value = builder.get_variable(witness_index); - - fr::serialize_to_buffer(value, &fr_bytes[0]); - - signature_cr.s[i - 32] = fr_bytes.back(); - } - - signature_cr.v = 27; - - return signature_cr; -} - template secp256k1_ct::g1_ct ecdsa_convert_inputs(Builder* ctx, const secp256k1::g1::affine_element& input) { @@ -63,9 +25,9 @@ secp256k1_ct::g1_ct ecdsa_convert_inputs(Builder* ctx, const secp256k1::g1::affi // vector of bytes here, assumes that the witness indices point to a field element which can be represented // with just a byte. // notice that this function truncates each field_element to a byte -template -bb::stdlib::byte_array ecdsa_vector_of_bytes_to_byte_array(Builder& builder, - std::vector vector_of_bytes) +template +bb::stdlib::byte_array ecdsa_array_of_bytes_to_byte_array(Builder& builder, + std::array vector_of_bytes) { using byte_array_ct = bb::stdlib::byte_array; using field_ct = bb::stdlib::field_t; @@ -106,9 +68,9 @@ void create_ecdsa_k1_verify_constraints(Builder& builder, auto new_sig = ecdsa_convert_signature(builder, input.signature); - byte_array_ct message = ecdsa_vector_of_bytes_to_byte_array(builder, input.hashed_message); - auto pub_key_x_byte_arr = ecdsa_vector_of_bytes_to_byte_array(builder, input.pub_x_indices); - auto pub_key_y_byte_arr = ecdsa_vector_of_bytes_to_byte_array(builder, input.pub_y_indices); + byte_array_ct message = ecdsa_array_of_bytes_to_byte_array(builder, input.hashed_message); + auto pub_key_x_byte_arr = ecdsa_array_of_bytes_to_byte_array(builder, input.pub_x_indices); + auto pub_key_y_byte_arr = ecdsa_array_of_bytes_to_byte_array(builder, input.pub_y_indices); auto pub_key_x_fq = typename secp256k1_ct::fq_ct(pub_key_x_byte_arr); auto pub_key_y_fq = typename secp256k1_ct::fq_ct(pub_key_y_byte_arr); @@ -153,11 +115,10 @@ void create_ecdsa_k1_verify_constraints(Builder& builder, template void dummy_ecdsa_constraint(Builder& builder, EcdsaSecp256k1Constraint const& input) { - std::vector pub_x_indices_; - std::vector pub_y_indices_; - std::vector signature_; - std::vector message_indices_; - signature_.resize(64); + std::array pub_x_indices_; + std::array pub_y_indices_; + std::array signature_; + std::array message_indices_; // Create a valid signature with a valid public key crypto::ecdsa_key_pair account; @@ -179,9 +140,9 @@ template void dummy_ecdsa_constraint(Builder& builder, EcdsaS uint32_t y_wit = builder.add_variable(pub_y_value.slice(248 - i * 8, 256 - i * 8)); uint32_t r_wit = builder.add_variable(signature.r[i]); uint32_t s_wit = builder.add_variable(signature.s[i]); - message_indices_.emplace_back(m_wit); - pub_x_indices_.emplace_back(x_wit); - pub_y_indices_.emplace_back(y_wit); + message_indices_[i] = m_wit; + pub_x_indices_[i] = x_wit; + pub_y_indices_[i] = y_wit; signature_[i] = r_wit; signature_[i + 32] = s_wit; } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp index 7dd69f6af90b..d5eb6e2df859 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp @@ -8,19 +8,19 @@ namespace acir_format { struct EcdsaSecp256k1Constraint { // This is the byte representation of the hashed message. - std::vector hashed_message; + std::array hashed_message; // This is the computed signature // - std::vector signature; + std::array signature; // This is the supposed public key which signed the // message, giving rise to the signature. // Since Fr does not have enough bits to represent // the prime field in secp256k1, a byte array is used. // Can also use low and hi where lo=128 bits - std::vector pub_x_indices; - std::vector pub_y_indices; + std::array pub_x_indices; + std::array pub_y_indices; // This is the result of verifying the signature uint32_t result; @@ -37,11 +37,51 @@ void create_ecdsa_k1_verify_constraints(Builder& builder, template void dummy_ecdsa_constraint(Builder& builder, EcdsaSecp256k1Constraint const& input); -template -crypto::ecdsa_signature ecdsa_convert_signature(Builder& builder, std::vector signature); witness_ct ecdsa_index_to_witness(Builder& builder, uint32_t index); +template +bb::stdlib::byte_array ecdsa_array_of_bytes_to_byte_array(Builder& builder, + std::array vector_of_bytes); + +// We have the implementation of this template in the header as this method is used +// by other ecdsa constraints over different curves (e.g. secp256r1). +// gcc needs to be able to see the implementation order to generate code for +// all Builder specializations (e.g. bb::Goblin::Builder vs. bb::UltraCircuitBuilder) template -bb::stdlib::byte_array ecdsa_vector_of_bytes_to_byte_array(Builder& builder, - std::vector vector_of_bytes); +crypto::ecdsa_signature ecdsa_convert_signature(Builder& builder, std::array signature) +{ + + crypto::ecdsa_signature signature_cr; + + // Get the witness assignment for each witness index + // Write the witness assignment to the byte_array + + for (unsigned int i = 0; i < 32; i++) { + auto witness_index = signature[i]; + + std::vector fr_bytes(sizeof(fr)); + + fr value = builder.get_variable(witness_index); + + fr::serialize_to_buffer(value, &fr_bytes[0]); + + signature_cr.r[i] = fr_bytes.back(); + } + + for (unsigned int i = 32; i < 64; i++) { + auto witness_index = signature[i]; + + std::vector fr_bytes(sizeof(fr)); + + fr value = builder.get_variable(witness_index); + + fr::serialize_to_buffer(value, &fr_bytes[0]); + + signature_cr.s[i - 32] = fr_bytes.back(); + } + + signature_cr.v = 27; + + return signature_cr; +} } // namespace acir_format diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp index 1986460b53c4..0a11adb97be2 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp @@ -37,35 +37,35 @@ size_t generate_ecdsa_constraint(EcdsaSecp256k1Constraint& ecdsa_constraint, Wit uint256_t pub_x_value = account.public_key.x; uint256_t pub_y_value = account.public_key.y; - std::vector message_in; - std::vector pub_x_indices_in; - std::vector pub_y_indices_in; - std::vector signature_in; + std::array message_in; + std::array pub_x_indices_in; + std::array pub_y_indices_in; + std::array signature_in; size_t offset = 0; for (size_t i = 0; i < hashed_message.size(); ++i) { - message_in.emplace_back(i + offset); + message_in[i] = static_cast(i + offset); const auto byte = static_cast(hashed_message[i]); witness_values.emplace_back(byte); } offset += message_in.size(); for (size_t i = 0; i < 32; ++i) { - pub_x_indices_in.emplace_back(i + offset); + pub_x_indices_in[i] = static_cast(i + offset); witness_values.emplace_back(pub_x_value.slice(248 - i * 8, 256 - i * 8)); } offset += pub_x_indices_in.size(); for (size_t i = 0; i < 32; ++i) { - pub_y_indices_in.emplace_back(i + offset); + pub_y_indices_in[i] = static_cast(i + offset); witness_values.emplace_back(pub_y_value.slice(248 - i * 8, 256 - i * 8)); } offset += pub_y_indices_in.size(); for (size_t i = 0; i < 32; ++i) { - signature_in.emplace_back(i + offset); + signature_in[i] = static_cast(i + offset); witness_values.emplace_back(signature.r[i]); } offset += signature.r.size(); for (size_t i = 0; i < 32; ++i) { - signature_in.emplace_back(i + offset); + signature_in[i + 32] = static_cast(i + offset); witness_values.emplace_back(signature.s[i]); } offset += signature.s.size(); @@ -112,7 +112,8 @@ TEST_F(ECDSASecp256k1, TestECDSAConstraintSucceed) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; @@ -160,7 +161,8 @@ TEST_F(ECDSASecp256k1, TestECDSACompilesForVerifier) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; @@ -203,7 +205,8 @@ TEST_F(ECDSASecp256k1, TestECDSAConstraintFail) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.cpp index 7ac186878085..9554c269d5f0 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.cpp @@ -33,6 +33,7 @@ void create_ecdsa_r1_verify_constraints(Builder& builder, using secp256r1_ct = bb::stdlib::secp256r1; using bool_ct = bb::stdlib::bool_t; using field_ct = bb::stdlib::field_t; + using byte_array_ct = bb::stdlib::byte_array; if (has_valid_witness_assignments == false) { dummy_ecdsa_constraint(builder, input); @@ -40,9 +41,9 @@ void create_ecdsa_r1_verify_constraints(Builder& builder, auto new_sig = ecdsa_convert_signature(builder, input.signature); - auto message = ecdsa_vector_of_bytes_to_byte_array(builder, input.hashed_message); - auto pub_key_x_byte_arr = ecdsa_vector_of_bytes_to_byte_array(builder, input.pub_x_indices); - auto pub_key_y_byte_arr = ecdsa_vector_of_bytes_to_byte_array(builder, input.pub_y_indices); + byte_array_ct message = ecdsa_array_of_bytes_to_byte_array(builder, input.hashed_message); + auto pub_key_x_byte_arr = ecdsa_array_of_bytes_to_byte_array(builder, input.pub_x_indices); + auto pub_key_y_byte_arr = ecdsa_array_of_bytes_to_byte_array(builder, input.pub_y_indices); auto pub_key_x_fq = typename secp256r1_ct::fq_ct(pub_key_x_byte_arr); auto pub_key_y_fq = typename secp256r1_ct::fq_ct(pub_key_y_byte_arr); @@ -87,11 +88,10 @@ void create_ecdsa_r1_verify_constraints(Builder& builder, template void dummy_ecdsa_constraint(Builder& builder, EcdsaSecp256r1Constraint const& input) { - std::vector pub_x_indices_; - std::vector pub_y_indices_; - std::vector signature_; - std::vector message_indices_; - signature_.resize(64); + std::array pub_x_indices_; + std::array pub_y_indices_; + std::array signature_; + std::array message_indices_; // Create a valid signature with a valid public key std::string message_string = "Instructions unclear, ask again later."; @@ -121,9 +121,9 @@ template void dummy_ecdsa_constraint(Builder& builder, EcdsaS uint32_t y_wit = builder.add_variable(pub_y_value.slice(248 - i * 8, 256 - i * 8)); uint32_t r_wit = builder.add_variable(signature.r[i]); uint32_t s_wit = builder.add_variable(signature.s[i]); - message_indices_.emplace_back(m_wit); - pub_x_indices_.emplace_back(x_wit); - pub_y_indices_.emplace_back(y_wit); + message_indices_[i] = m_wit; + pub_x_indices_[i] = x_wit; + pub_y_indices_[i] = y_wit; signature_[i] = r_wit; signature_[i + 32] = s_wit; } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.hpp index 1f5972ba609a..701a0e23c419 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.hpp @@ -6,22 +6,22 @@ namespace acir_format { struct EcdsaSecp256r1Constraint { // This is the byte representation of the hashed message. - std::vector hashed_message; + std::array hashed_message; // This is the supposed public key which signed the // message, giving rise to the signature. // Since Fr does not have enough bits to represent // the prime field in secp256r1, a byte array is used. // Can also use low and hi where lo=128 bits - std::vector pub_x_indices; - std::vector pub_y_indices; + std::array pub_x_indices; + std::array pub_y_indices; // This is the result of verifying the signature uint32_t result; // This is the computed signature // - std::vector signature; + std::array signature; friend bool operator==(EcdsaSecp256r1Constraint const& lhs, EcdsaSecp256r1Constraint const& rhs) = default; }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp index 462172d3c4ea..6cf542bc2d6e 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp @@ -22,35 +22,35 @@ size_t generate_r1_constraints(EcdsaSecp256r1Constraint& ecdsa_r1_constraint, ecdsa_signature signature) { - std::vector message_in; - std::vector pub_x_indices_in; - std::vector pub_y_indices_in; - std::vector signature_in; + std::array message_in; + std::array pub_x_indices_in; + std::array pub_y_indices_in; + std::array signature_in; size_t offset = 0; for (size_t i = 0; i < hashed_message.size(); ++i) { - message_in.emplace_back(i + offset); + message_in[i] = static_cast(i + offset); const auto byte = static_cast(hashed_message[i]); witness_values.emplace_back(byte); } offset += message_in.size(); for (size_t i = 0; i < 32; ++i) { - pub_x_indices_in.emplace_back(i + offset); + pub_x_indices_in[i] = static_cast(i + offset); witness_values.emplace_back(pub_x_value.slice(248 - i * 8, 256 - i * 8)); } offset += pub_x_indices_in.size(); for (size_t i = 0; i < 32; ++i) { - pub_y_indices_in.emplace_back(i + offset); + pub_y_indices_in[i] = static_cast(i + offset); witness_values.emplace_back(pub_y_value.slice(248 - i * 8, 256 - i * 8)); } offset += pub_y_indices_in.size(); for (size_t i = 0; i < 32; ++i) { - signature_in.emplace_back(i + offset); + signature_in[i] = static_cast(i + offset); witness_values.emplace_back(signature.r[i]); } offset += signature.r.size(); for (size_t i = 0; i < 32; ++i) { - signature_in.emplace_back(i + offset); + signature_in[i + 32] = static_cast(i + offset); witness_values.emplace_back(signature.s[i]); } offset += signature.s.size(); @@ -146,7 +146,8 @@ TEST(ECDSASecp256r1, test_hardcoded) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; @@ -196,7 +197,8 @@ TEST(ECDSASecp256r1, TestECDSAConstraintSucceed) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; @@ -244,7 +246,8 @@ TEST(ECDSASecp256r1, TestECDSACompilesForVerifier) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; auto builder = create_circuit(constraint_system); @@ -287,7 +290,8 @@ TEST(ECDSASecp256r1, TestECDSAConstraintFail) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {}, }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp index 6ce3ccdc5f2a..14139cba4191 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/keccak_constraint.hpp @@ -16,8 +16,8 @@ struct HashInput { }; struct Keccakf1600 { - std::vector state; - std::vector result; + std::array state; + std::array result; // For serialization, update with any new fields MSGPACK_FIELDS(state, result); @@ -26,7 +26,7 @@ struct Keccakf1600 { struct KeccakConstraint { std::vector inputs; - std::vector result; + std::array result; uint32_t var_message_size; // For serialization, update with any new fields diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp index 7ca36a784146..f509c262782a 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp @@ -52,7 +52,8 @@ TEST_F(Poseidon2Tests, TestPoseidon2Permutation) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {} }; WitnessVector witness{ diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp index d35e15768fab..bbf7768abc91 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp @@ -104,7 +104,8 @@ Builder create_inner_circuit() .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = { expr_a, expr_b, expr_c, expr_d }, + .poly_triple_constraints = { expr_a, expr_b, expr_c, expr_d }, + .quad_constraints = {}, .block_constraints = {} }; uint256_t inverse_of_five = fr(5).invert(); @@ -260,7 +261,8 @@ Builder create_outer_circuit(std::vector& inner_circuits) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {} }; auto outer_circuit = create_circuit(constraint_system, /*size_hint*/ 0, witness); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp index b4d7f4737d5d..bcb6e0264902 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.cpp @@ -7,7 +7,7 @@ namespace acir_format { using namespace bb::stdlib; template -crypto::schnorr_signature convert_signature(Builder& builder, std::vector signature) +crypto::schnorr_signature convert_signature(Builder& builder, std::array signature) { crypto::schnorr_signature signature_cr; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp index a22c2abb5672..a7dbc2b03445 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/schnorr_verify.hpp @@ -20,7 +20,7 @@ struct SchnorrConstraint { // This is the computed signature // - std::vector signature; + std::array signature; friend bool operator==(SchnorrConstraint const& lhs, SchnorrConstraint const& rhs) = default; }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index 3e01fd1f1559..5fd065434679 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -54,7 +54,7 @@ struct BlackBoxFuncCall { struct SHA256 { std::vector inputs; - std::vector outputs; + std::array outputs; friend bool operator==(const SHA256&, const SHA256&); std::vector bincodeSerialize() const; @@ -63,7 +63,7 @@ struct BlackBoxFuncCall { struct Blake2s { std::vector inputs; - std::vector outputs; + std::array outputs; friend bool operator==(const Blake2s&, const Blake2s&); std::vector bincodeSerialize() const; @@ -72,7 +72,7 @@ struct BlackBoxFuncCall { struct Blake3 { std::vector inputs; - std::vector outputs; + std::array outputs; friend bool operator==(const Blake3&, const Blake3&); std::vector bincodeSerialize() const; @@ -82,7 +82,7 @@ struct BlackBoxFuncCall { struct SchnorrVerify { Program::FunctionInput public_key_x; Program::FunctionInput public_key_y; - std::vector signature; + std::array signature; std::vector message; Program::Witness output; @@ -112,10 +112,10 @@ struct BlackBoxFuncCall { }; struct EcdsaSecp256k1 { - std::vector public_key_x; - std::vector public_key_y; - std::vector signature; - std::vector hashed_message; + std::array public_key_x; + std::array public_key_y; + std::array signature; + std::array hashed_message; Program::Witness output; friend bool operator==(const EcdsaSecp256k1&, const EcdsaSecp256k1&); @@ -124,10 +124,10 @@ struct BlackBoxFuncCall { }; struct EcdsaSecp256r1 { - std::vector public_key_x; - std::vector public_key_y; - std::vector signature; - std::vector hashed_message; + std::array public_key_x; + std::array public_key_y; + std::array signature; + std::array hashed_message; Program::Witness output; friend bool operator==(const EcdsaSecp256r1&, const EcdsaSecp256r1&); @@ -160,7 +160,7 @@ struct BlackBoxFuncCall { struct Keccak256 { std::vector inputs; Program::FunctionInput var_message_size; - std::vector outputs; + std::array outputs; friend bool operator==(const Keccak256&, const Keccak256&); std::vector bincodeSerialize() const; @@ -168,8 +168,8 @@ struct BlackBoxFuncCall { }; struct Keccakf1600 { - std::vector inputs; - std::vector outputs; + std::array inputs; + std::array outputs; friend bool operator==(const Keccakf1600&, const Keccakf1600&); std::vector bincodeSerialize() const; @@ -257,9 +257,9 @@ struct BlackBoxFuncCall { }; struct Sha256Compression { - std::vector inputs; - std::vector hash_values; - std::vector outputs; + std::array inputs; + std::array hash_values; + std::array outputs; friend bool operator==(const Sha256Compression&, const Sha256Compression&); std::vector bincodeSerialize() const; @@ -966,6 +966,9 @@ struct BrilligOpcode { }; struct Trap { + uint64_t revert_data_offset; + uint64_t revert_data_size; + friend bool operator==(const Trap&, const Trap&); std::vector bincodeSerialize() const; static Trap bincodeDeserialize(std::vector); @@ -1123,6 +1126,17 @@ struct Opcode { static MemoryInit bincodeDeserialize(std::vector); }; + struct BrilligCall { + uint32_t id; + std::vector inputs; + std::vector outputs; + std::optional predicate; + + friend bool operator==(const BrilligCall&, const BrilligCall&); + std::vector bincodeSerialize() const; + static BrilligCall bincodeDeserialize(std::vector); + }; + struct Call { uint32_t id; std::vector inputs; @@ -1134,7 +1148,7 @@ struct Opcode { static Call bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const Opcode&, const Opcode&); std::vector bincodeSerialize() const; @@ -1213,8 +1227,17 @@ struct Circuit { static Circuit bincodeDeserialize(std::vector); }; +struct BrilligBytecode { + std::vector bytecode; + + friend bool operator==(const BrilligBytecode&, const BrilligBytecode&); + std::vector bincodeSerialize() const; + static BrilligBytecode bincodeDeserialize(std::vector); +}; + struct Program { std::vector functions; + std::vector unconstrained_functions; friend bool operator==(const Program&, const Program&); std::vector bincodeSerialize() const; @@ -4878,6 +4901,56 @@ Program::Brillig serde::Deserializable::deserialize(Deserializ namespace Program { +inline bool operator==(const BrilligBytecode& lhs, const BrilligBytecode& rhs) +{ + if (!(lhs.bytecode == rhs.bytecode)) { + return false; + } + return true; +} + +inline std::vector BrilligBytecode::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BrilligBytecode BrilligBytecode::bincodeDeserialize(std::vector input) +{ + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw_or_abort("Some input bytes were not read"); + } + return value; +} + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::BrilligBytecode& obj, + Serializer& serializer) +{ + serializer.increase_container_depth(); + serde::Serializable::serialize(obj.bytecode, serializer); + serializer.decrease_container_depth(); +} + +template <> +template +Program::BrilligBytecode serde::Deserializable::deserialize(Deserializer& deserializer) +{ + deserializer.increase_container_depth(); + Program::BrilligBytecode obj; + obj.bytecode = serde::Deserializable::deserialize(deserializer); + deserializer.decrease_container_depth(); + return obj; +} + +namespace Program { + inline bool operator==(const BrilligInputs& lhs, const BrilligInputs& rhs) { if (!(lhs.value == rhs.value)) { @@ -5990,6 +6063,12 @@ namespace Program { inline bool operator==(const BrilligOpcode::Trap& lhs, const BrilligOpcode::Trap& rhs) { + if (!(lhs.revert_data_offset == rhs.revert_data_offset)) { + return false; + } + if (!(lhs.revert_data_size == rhs.revert_data_size)) { + return false; + } return true; } @@ -6016,7 +6095,10 @@ template <> template void serde::Serializable::serialize(const Program::BrilligOpcode::Trap& obj, Serializer& serializer) -{} +{ + serde::Serializable::serialize(obj.revert_data_offset, serializer); + serde::Serializable::serialize(obj.revert_data_size, serializer); +} template <> template @@ -6024,6 +6106,8 @@ Program::BrilligOpcode::Trap serde::Deserializable Deserializer& deserializer) { Program::BrilligOpcode::Trap obj; + obj.revert_data_offset = serde::Deserializable::deserialize(deserializer); + obj.revert_data_size = serde::Deserializable::deserialize(deserializer); return obj; } @@ -7417,6 +7501,68 @@ Program::Opcode::MemoryInit serde::Deserializable:: namespace Program { +inline bool operator==(const Opcode::BrilligCall& lhs, const Opcode::BrilligCall& rhs) +{ + if (!(lhs.id == rhs.id)) { + return false; + } + if (!(lhs.inputs == rhs.inputs)) { + return false; + } + if (!(lhs.outputs == rhs.outputs)) { + return false; + } + if (!(lhs.predicate == rhs.predicate)) { + return false; + } + return true; +} + +inline std::vector Opcode::BrilligCall::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline Opcode::BrilligCall Opcode::BrilligCall::bincodeDeserialize(std::vector input) +{ + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw_or_abort("Some input bytes were not read"); + } + return value; +} + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::Opcode::BrilligCall& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.id, serializer); + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.outputs, serializer); + serde::Serializable::serialize(obj.predicate, serializer); +} + +template <> +template +Program::Opcode::BrilligCall serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Program::Opcode::BrilligCall obj; + obj.id = serde::Deserializable::deserialize(deserializer); + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.outputs = serde::Deserializable::deserialize(deserializer); + obj.predicate = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Program { + inline bool operator==(const Opcode::Call& lhs, const Opcode::Call& rhs) { if (!(lhs.id == rhs.id)) { @@ -7630,6 +7776,9 @@ inline bool operator==(const Program& lhs, const Program& rhs) if (!(lhs.functions == rhs.functions)) { return false; } + if (!(lhs.unconstrained_functions == rhs.unconstrained_functions)) { + return false; + } return true; } @@ -7658,6 +7807,7 @@ void serde::Serializable::serialize(const Program::Program& ob { serializer.increase_container_depth(); serde::Serializable::serialize(obj.functions, serializer); + serde::Serializable::serialize(obj.unconstrained_functions, serializer); serializer.decrease_container_depth(); } @@ -7668,6 +7818,8 @@ Program::Program serde::Deserializable::deserialize(Deserializ deserializer.increase_container_depth(); Program::Program obj; obj.functions = serde::Deserializable::deserialize(deserializer); + obj.unconstrained_functions = + serde::Deserializable::deserialize(deserializer); deserializer.decrease_container_depth(); return obj; } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp index 0c36058393a1..560f8e915d2b 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp @@ -17,7 +17,7 @@ struct Sha256Input { struct Sha256Constraint { std::vector inputs; - std::vector result; + std::array result; friend bool operator==(Sha256Constraint const& lhs, Sha256Constraint const& rhs) = default; // for serialization, update with any new fields @@ -25,9 +25,9 @@ struct Sha256Constraint { }; struct Sha256Compression { - std::vector inputs; - std::vector hash_values; - std::vector result; + std::array inputs; + std::array hash_values; + std::array result; friend bool operator==(Sha256Compression const& lhs, Sha256Compression const& rhs) = default; // for serialization, update with any new fields diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp index 8e770aa4f40e..6266253ee552 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp @@ -17,13 +17,13 @@ class Sha256Tests : public ::testing::Test { TEST_F(Sha256Tests, TestSha256Compression) { - std::vector inputs; - for (uint32_t i = 1; i < 17; ++i) { - inputs.push_back({ .witness = i, .num_bits = 32 }); + std::array inputs; + for (size_t i = 0; i < 16; ++i) { + inputs[i] = { .witness = static_cast(i + 1), .num_bits = 32 }; } - std::vector hash_values; - for (uint32_t i = 17; i < 25; ++i) { - hash_values.push_back({ .witness = i, .num_bits = 32 }); + std::array hash_values; + for (size_t i = 0; i < 8; ++i) { + hash_values[i] = { .witness = static_cast(i + 17), .num_bits = 32 }; } Sha256Compression sha256_compression{ .inputs = inputs, @@ -54,7 +54,8 @@ TEST_F(Sha256Tests, TestSha256Compression) .bigint_from_le_bytes_constraints = {}, .bigint_to_le_bytes_constraints = {}, .bigint_operations = {}, - .constraints = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, .block_constraints = {} }; WitnessVector witness{ 0, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp index 9ce4baf73dd8..05caf1ace288 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp @@ -31,7 +31,6 @@ const std::unordered_map Bytecode::OPERANDS_NUM = { //// Execution Environment //{OpCode::ADDRESS, }, //{OpCode::STORAGEADDRESS, }, - //{OpCode::ORIGIN, }, //{OpCode::SENDER, }, //{OpCode::PORTAL, }, //{OpCode::FEEPERL1GAS, }, @@ -116,7 +115,6 @@ bool Bytecode::has_in_tag(OpCode const op_code) switch (op_code) { case OpCode::ADDRESS: case OpCode::STORAGEADDRESS: - case OpCode::ORIGIN: case OpCode::SENDER: case OpCode::PORTAL: case OpCode::FEEPERL1GAS: diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp index 8f04ddcd2d38..98adf14ab291 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp @@ -40,7 +40,6 @@ enum class OpCode : uint8_t { // Execution Environment ADDRESS, STORAGEADDRESS, - ORIGIN, SENDER, PORTAL, FEEPERL1GAS, diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp index caf1b1855346..0e7fdce22056 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp @@ -33,46 +33,6 @@ class AvmInterTableTests : public ::testing::Test { * relation being tested. ******************************************************************************/ -// Error tag propagation from memory trace back to the main trace. -TEST_F(AvmInterTableTests, tagErrNotCopiedInMain) -{ - // Equality operation on U128 and second operand is of type U16. - trace_builder.op_set(0, 32, 18, AvmMemoryTag::U128); - trace_builder.op_set(0, 32, 76, AvmMemoryTag::U16); - trace_builder.op_eq(0, 18, 76, 65, AvmMemoryTag::U128); - trace_builder.halt(); - auto trace = trace_builder.finalize(); - - // Find the row with equality operation and mutate the error tag. - auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_eq == 1; }); - ASSERT_EQ(row->avm_main_tag_err, FF(1)); // Sanity check that the error tag is set. - row->avm_main_tag_err = 0; - row->avm_main_alu_sel = 1; // We have to activate ALU trace if no error tag is present. - auto const clk = row->avm_main_clk; - - // Create a valid ALU entry for this equality operation. - auto& alu_row = trace.at(1); - alu_row.avm_alu_clk = clk; - alu_row.avm_alu_alu_sel = 1; - alu_row.avm_alu_ia = 32; - alu_row.avm_alu_ib = 32; - alu_row.avm_alu_ic = 1; - alu_row.avm_alu_op_eq = 1; - alu_row.avm_alu_in_tag = static_cast(AvmMemoryTag::U128); - alu_row.avm_alu_u128_tag = 1; - - // Adjust the output of the computation as it would have been performed without tag check. - row->avm_main_ic = 1; - // Find the memory row pertaining to write operation from Ic. - auto mem_row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_STORE_C; - }); - - // Adjust the output in the memory trace. - mem_row->avm_mem_val = 1; - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "INCL_MAIN_TAG_ERR"); -} - /****************************************************************************** * MAIN <-------> ALU ******************************************************************************/ @@ -173,7 +133,253 @@ TEST_F(AvmPermMainAluNegativeTests, removeAluSelector) } /****************************************************************************** - * MAIN <-------> ALU + * REGISTER RANGE CHECKS (MAIN <-------> ALU) + ******************************************************************************/ +class AvmRangeCheckNegativeTests : public AvmInterTableTests { + protected: + std::vector trace; + size_t main_idx; + size_t mem_idx; + size_t alu_idx; + + void genTraceAdd(uint128_t const& a, uint128_t const& b, uint128_t const& c, AvmMemoryTag tag) + { + trace_builder.op_set(0, a, 0, tag); + trace_builder.op_set(0, b, 1, tag); + trace_builder.op_add(0, 0, 1, 2, tag); // 7 + 8 = 15 + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + // Find the row with addition operation and retrieve clk. + auto row = + std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_add == FF(1); }); + + ASSERT_TRUE(row != trace.end()); + ASSERT_EQ(row->avm_main_ia, FF(uint256_t::from_uint128(a))); + ASSERT_EQ(row->avm_main_ib, FF(uint256_t::from_uint128(b))); + ASSERT_EQ(row->avm_main_ic, FF(uint256_t::from_uint128(c))); + auto clk = row->avm_main_clk; + + // Find the corresponding Alu trace row + auto alu_row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { return r.avm_alu_clk == clk; }); + ASSERT_TRUE(alu_row != trace.end()); + + // Find memory trace entry related to storing output (intermediate register Ic) in memory. + auto mem_row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { + return r.avm_mem_clk == clk && r.avm_mem_op_c == FF(1) && r.avm_mem_rw == FF(1); + }); + ASSERT_TRUE(mem_row != trace.end()); + + main_idx = static_cast(row - trace.begin()); + alu_idx = static_cast(alu_row - trace.begin()); + mem_idx = static_cast(mem_row - trace.begin()); + }; +}; + +// Out-of-range value in register u8_r0 +TEST_F(AvmRangeCheckNegativeTests, additionU8Reg0) +{ + genTraceAdd(7, 8, 15, AvmMemoryTag::U8); + + // We mutate the result 15 to 15 - 2^254 mod p + // The value 15 - 2^254 mod p is set in register u8_r0 and 2^246 in u8_r1 + // Therefore, u8_r0 + 2^8 * u8_r1 mod p = 15 + // All constraints except range checks on u8_r0, u8_r1 are satisfied. + + FF const fake_c = FF(15).add(-FF(2).pow(254)); + auto& row = trace.at(main_idx); + auto& mem_row = trace.at(mem_idx); + auto& alu_row = trace.at(alu_idx); + + row.avm_main_ic = fake_c; + mem_row.avm_mem_val = fake_c; + alu_row.avm_alu_ic = fake_c; + + ASSERT_EQ(alu_row.avm_alu_u8_r0, 15); + ASSERT_EQ(alu_row.avm_alu_u8_r1, 0); + + alu_row.avm_alu_u8_r0 = fake_c; + alu_row.avm_alu_u8_r1 = FF(2).pow(246); + + // We first try to validate without any range check counters adjustment. + auto trace_same_cnt = trace; + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace_same_cnt)), "LOOKUP_U8_0"); + + // Decrement the counter for former lookup values 15 resp. 0 for u8_r0 resp. u8_r1. + trace.at(15 + 1).lookup_u8_0_counts -= FF(1); + trace.at(1).lookup_u8_1_counts -= FF(1); + + // One cannot add the new values in counters as they are out of range. + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U8_0"); +} + +// Out-of-range value in register u8_r1 +TEST_F(AvmRangeCheckNegativeTests, additionU8Reg1) +{ + genTraceAdd(19, 20, 39, AvmMemoryTag::U8); + auto& row = trace.at(main_idx); + auto& mem_row = trace.at(mem_idx); + auto& alu_row = trace.at(alu_idx); + + // a + b = u8_r0 + 2^8 * u8_r1 (mod p) + // We recall that p-1 is a multiple of a large power of two. + // We select a maximal u8_r1 such that u8_r0 is still of type U8. + // Namely, we pick (p-1)/2^8 so that we can replace c (i.e., u8_r0) with 40 as + // 39 = 40 + p - 1 (mod p) + uint256_t const r1 = (uint256_t(FF::modulus) - 1) / 256; + FF const fake_c = FF(40); + + row.avm_main_ic = fake_c; + mem_row.avm_mem_val = fake_c; + alu_row.avm_alu_ic = fake_c; + + ASSERT_EQ(alu_row.avm_alu_u8_r0, 39); + ASSERT_EQ(alu_row.avm_alu_u8_r1, 0); + + alu_row.avm_alu_u8_r0 = fake_c; + alu_row.avm_alu_u8_r1 = FF(r1); + + // We adjust counter to pass range check lookup for u8_r0 + trace.at(39 + 1).lookup_u8_0_counts -= FF(1); + trace.at(40 + 1).lookup_u8_0_counts += FF(1); + + auto trace_same_cnt = trace; + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace_same_cnt)), "LOOKUP_U8_1"); + + // Second attempt by decreasing counter for u8_r1 range check lookup + trace.at(1).lookup_u8_1_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U8_1"); +} + +// Out-of-range value in register u16_r0 +TEST_F(AvmRangeCheckNegativeTests, additionU16Reg0) +{ + genTraceAdd(1200, 2000, 3200, AvmMemoryTag::U16); + auto& row = trace.at(main_idx); + auto& mem_row = trace.at(mem_idx); + auto& alu_row = trace.at(alu_idx); + + // a + b = u8_r0 + 2^8 * u8_r1 + 2^16 * u16_r0 (mod p) + // We recall that p-1 is a multiple of a large power of two. + // We select a maximal u16_r0 such that u8_r0 is still of type U16. + // Namely, we pick (p-1)/2^16 so that we can replace c with 3201 as + // 3201 = 3200 + p - 1 (mod p) + uint256_t const u16_r0 = (uint256_t(FF::modulus) - 1) / 65536; + FF const fake_c = FF(3201); + + row.avm_main_ic = fake_c; + mem_row.avm_mem_val = fake_c; + alu_row.avm_alu_ic = fake_c; + + ASSERT_EQ(alu_row.avm_alu_u8_r0, FF(128)); // 3200 % 256 = 128 + ASSERT_EQ(alu_row.avm_alu_u8_r1, FF(12)); // 3200/256 = 12 + ASSERT_EQ(alu_row.avm_alu_u16_r0, 0); + + alu_row.avm_alu_u8_r0 = FF(129); // 3201 % 256 = 129 + // alu_row.avm_alu_u8_r1 = FF(r1); // Does not change 3201/256 = 12 + alu_row.avm_alu_u16_r0 = FF(u16_r0); + + // We adjust counter to pass range check lookup for u8_r0 + trace.at(128 + 1).lookup_u8_0_counts -= FF(1); + trace.at(129 + 1).lookup_u8_0_counts += FF(1); + + auto trace_same_cnt = trace; + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace_same_cnt)), "LOOKUP_U16_0"); + + // Second attempt by decreasing counter for u16_r0 range check lookup + trace.at(1).lookup_u16_0_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U16_0"); +} + +// Out-of-range value in registers u16_r7, .... u16_r14 +// These registers are not involved for the arithmetic +// relations of the addition but the range checks are currently +// enabled. + +// U16_R7 +TEST_F(AvmRangeCheckNegativeTests, additionU16Reg7) +{ + genTraceAdd(4500, 45, 4545, AvmMemoryTag::U16); + auto trace_original = trace; + + auto& alu_row = trace.at(alu_idx); + alu_row.avm_alu_u16_r7 = FF(235655); + + auto trace_same_cnt = trace; + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace_same_cnt)), "LOOKUP_U16_7"); + + // Second attempt by decreasing counter for u16_r0 range check lookup + trace.at(1).lookup_u16_7_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U16_7"); +} + +// Subsequent range checks are attempted only after counter decrease. + +// U16_R8 +TEST_F(AvmRangeCheckNegativeTests, additionU16Reg8) +{ + genTraceAdd(4500, 45, 4545, AvmMemoryTag::U16); + trace.at(alu_idx).avm_alu_u16_r8 = FF(235655); + trace.at(1).lookup_u16_8_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U16_8"); +} + +// U16_R9 +TEST_F(AvmRangeCheckNegativeTests, additionU16Reg9) +{ + genTraceAdd(4500, 45, 4545, AvmMemoryTag::U16); + trace.at(alu_idx).avm_alu_u16_r9 = FF(235655); + trace.at(1).lookup_u16_9_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U16_9"); +} + +// U16_R10 +TEST_F(AvmRangeCheckNegativeTests, additionU16Reg10) +{ + genTraceAdd(4500, 45, 4545, AvmMemoryTag::U16); + trace.at(alu_idx).avm_alu_u16_r10 = FF(235655); + trace.at(1).lookup_u16_10_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U16_10"); +} + +// U16_R11 +TEST_F(AvmRangeCheckNegativeTests, additionU16Reg11) +{ + genTraceAdd(4500, 45, 4545, AvmMemoryTag::U16); + trace.at(alu_idx).avm_alu_u16_r11 = FF(235655); + trace.at(1).lookup_u16_11_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U16_11"); +} + +// U16_R12 +TEST_F(AvmRangeCheckNegativeTests, additionU16Reg12) +{ + genTraceAdd(4500, 45, 4545, AvmMemoryTag::U16); + trace.at(alu_idx).avm_alu_u16_r12 = FF(235655); + trace.at(1).lookup_u16_12_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U16_12"); +} + +// U16_R13 +TEST_F(AvmRangeCheckNegativeTests, additionU16Reg13) +{ + genTraceAdd(4500, 45, 4545, AvmMemoryTag::U16); + trace.at(alu_idx).avm_alu_u16_r13 = FF(235655); + trace.at(1).lookup_u16_13_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U16_13"); +} + +// U16_R14 +TEST_F(AvmRangeCheckNegativeTests, additionU16Reg14) +{ + genTraceAdd(4500, 45, 4545, AvmMemoryTag::U16); + trace.at(alu_idx).avm_alu_u16_r14 = FF(235655); + trace.at(1).lookup_u16_14_counts -= FF(1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "LOOKUP_U16_14"); +} + +/****************************************************************************** + * MAIN <-------> MEM ******************************************************************************/ class AvmPermMainMemNegativeTests : public AvmInterTableTests { protected: @@ -231,6 +437,45 @@ class AvmPermMainMemNegativeTests : public AvmInterTableTests { mem_idx_c = static_cast(mem_row_c - trace.begin()); } }; +// Error tag propagation from memory trace back to the main trace. +TEST_F(AvmPermMainMemNegativeTests, tagErrNotCopiedInMain) +{ + // Equality operation on U128 and second operand is of type U16. + trace_builder.op_set(0, 32, 18, AvmMemoryTag::U128); + trace_builder.op_set(0, 32, 76, AvmMemoryTag::U16); + trace_builder.op_eq(0, 18, 76, 65, AvmMemoryTag::U128); + trace_builder.halt(); + auto trace = trace_builder.finalize(); + + // Find the row with equality operation and mutate the error tag. + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_eq == 1; }); + ASSERT_EQ(row->avm_main_tag_err, FF(1)); // Sanity check that the error tag is set. + row->avm_main_tag_err = 0; + row->avm_main_alu_sel = 1; // We have to activate ALU trace if no error tag is present. + auto const clk = row->avm_main_clk; + + // Create a valid ALU entry for this equality operation. + auto& alu_row = trace.at(1); + alu_row.avm_alu_clk = clk; + alu_row.avm_alu_alu_sel = 1; + alu_row.avm_alu_ia = 32; + alu_row.avm_alu_ib = 32; + alu_row.avm_alu_ic = 1; + alu_row.avm_alu_op_eq = 1; + alu_row.avm_alu_in_tag = static_cast(AvmMemoryTag::U128); + alu_row.avm_alu_u128_tag = 1; + + // Adjust the output of the computation as it would have been performed without tag check. + row->avm_main_ic = 1; + // Find the memory row pertaining to write operation from Ic. + auto mem_row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { + return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_STORE_C; + }); + + // Adjust the output in the memory trace. + mem_row->avm_mem_val = 1; + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "INCL_MAIN_TAG_ERR"); +} TEST_F(AvmPermMainMemNegativeTests, wrongValueIaInMem) { diff --git a/barretenberg/ts/CHANGELOG.md b/barretenberg/ts/CHANGELOG.md index 389e21f2d53d..8592c453620b 100644 --- a/barretenberg/ts/CHANGELOG.md +++ b/barretenberg/ts/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [0.35.1](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg.js-v0.35.0...barretenberg.js-v0.35.1) (2024-04-16) + + +### Miscellaneous + +* **barretenberg.js:** Synchronize aztec-packages versions + +## [0.35.0](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg.js-v0.34.0...barretenberg.js-v0.35.0) (2024-04-16) + + +### Features + +* Export poseidon2_permutation and add to foundation/crypto ([#5706](https://github.com/AztecProtocol/aztec-packages/issues/5706)) ([6b91e27](https://github.com/AztecProtocol/aztec-packages/commit/6b91e2776de8fd5b1f489b5cfeee83c7e0996c2e)) + + +### Miscellaneous + +* Don't strip bb wasm ([#5743](https://github.com/AztecProtocol/aztec-packages/issues/5743)) ([d4cb410](https://github.com/AztecProtocol/aztec-packages/commit/d4cb4108900f1fb6307de17be9ee3516d6023609)) +* TS hash wrappers cleanup ([#5691](https://github.com/AztecProtocol/aztec-packages/issues/5691)) ([7f8b09f](https://github.com/AztecProtocol/aztec-packages/commit/7f8b09fca6370b140870041a49692383a4db6551)) + ## [0.34.0](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg.js-v0.33.0...barretenberg.js-v0.34.0) (2024-04-10) diff --git a/barretenberg/ts/package.json b/barretenberg/ts/package.json index bc9e3a437442..888182337d63 100644 --- a/barretenberg/ts/package.json +++ b/barretenberg/ts/package.json @@ -1,6 +1,6 @@ { "name": "@aztec/bb.js", - "version": "0.34.0", + "version": "0.35.1", "homepage": "https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg/ts", "license": "MIT", "type": "module", diff --git a/barretenberg/ts/scripts/build_wasm.sh b/barretenberg/ts/scripts/build_wasm.sh index 6c108f6770a8..77a9fa8a314e 100755 --- a/barretenberg/ts/scripts/build_wasm.sh +++ b/barretenberg/ts/scripts/build_wasm.sh @@ -18,4 +18,4 @@ fi mkdir -p ./dest/node/barretenberg_wasm mkdir -p ./dest/node-cjs/barretenberg_wasm cp ../cpp/build-wasm-threads/bin/barretenberg.wasm ./dest/node/barretenberg_wasm/barretenberg-threads.wasm -cp ../cpp/build-wasm-threads/bin/barretenberg.wasm ./dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm \ No newline at end of file +cp ../cpp/build-wasm-threads/bin/barretenberg.wasm ./dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm diff --git a/boxes/Earthfile b/boxes/Earthfile index e96e5e681c89..35ebe466c69d 100644 --- a/boxes/Earthfile +++ b/boxes/Earthfile @@ -15,4 +15,4 @@ build: ENV AZTEC_CLI=/usr/src/yarn-project/cli/aztec-cli-dest RUN yarn && yarn build RUN npx -y playwright@1.42 install --with-deps - ENTRYPOINT ["/bin/sh", "-c"] \ No newline at end of file + ENTRYPOINT ["/bin/sh", "-c"] diff --git a/boxes/boxes/react/package.json b/boxes/boxes/react/package.json index ea7ded69c007..0cd42e16ae53 100644 --- a/boxes/boxes/react/package.json +++ b/boxes/boxes/react/package.json @@ -7,7 +7,7 @@ "main": "./dist/index.js", "scripts": { "compile": "cd src/contracts && ${AZTEC_NARGO:-aztec-nargo} compile", - "codegen": "${AZTEC_CLI:-aztec-cli} codegen src/contracts/target -o artifacts --ts", + "codegen": "${AZTEC_CLI:-aztec-cli} codegen src/contracts/target -o artifacts", "clean": "rm -rf ./dist .tsbuildinfo ./artifacts ./src/contracts/target", "prep": "yarn clean && yarn compile && yarn codegen", "dev": "yarn prep && webpack serve --mode development", diff --git a/boxes/boxes/vanilla/package.json b/boxes/boxes/vanilla/package.json index bed49cf08f8e..4e9c549afc6f 100644 --- a/boxes/boxes/vanilla/package.json +++ b/boxes/boxes/vanilla/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "compile": "cd src/contracts && ${AZTEC_NARGO:-aztec-nargo} compile", - "codegen": "${AZTEC_CLI:-aztec-cli} codegen src/contracts/target -o artifacts --ts", + "codegen": "${AZTEC_CLI:-aztec-cli} codegen src/contracts/target -o artifacts", "clean": "rm -rf ./dest .tsbuildinfo ./artifacts ./src/contracts/target", "prep": "yarn clean && yarn compile && yarn codegen && tsc -b", "dev": "yarn prep && webpack serve --mode development", diff --git a/boxes/contract-only/package.json b/boxes/contract-only/package.json index 361571253f83..93e8c27ca85c 100644 --- a/boxes/contract-only/package.json +++ b/boxes/contract-only/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "compile": "cd src && ${AZTEC_NARGO:-aztec-nargo} compile", - "codegen": "${AZTEC_CLI:-aztec-cli} codegen target -o artifacts --ts", + "codegen": "${AZTEC_CLI:-aztec-cli} codegen target -o artifacts", "clean": "rm -rf ./dest .tsbuildinfo ./artifacts ./target", "prep": "yarn clean && yarn compile && yarn codegen && tsc -b", "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --runInBand", diff --git a/build-system/scripts/deploy_npm b/build-system/scripts/deploy_npm index c4ca396282e6..577f074ce09e 100755 --- a/build-system/scripts/deploy_npm +++ b/build-system/scripts/deploy_npm @@ -71,3 +71,29 @@ else npm publish $TAG_ARG --access public fi fi + +# Verify deployment +echo "Verifying deployment of version $VERSION with tag $TAG" +END_TIME=$((SECONDS + 300)) # 5 minutes + +while [ $SECONDS -lt $END_TIME ]; do + # Check version and tag + if npm view "$PACKAGE_NAME@$VERSION" version >/dev/null 2>&1; then + # Extract tag info and check + if npm dist-tag ls "$PACKAGE_NAME" | grep -q "$TAG: $VERSION"; then + echo "Version $VERSION with tag $TAG successfully deployed ." + break + else + echo "Version $VERSION is available, but tag $TAG is not correctly set." + fi + else + echo "Waiting for version $VERSION to be available..." + fi + sleep 5 +done + +# Final check to confirm both version and tag are correctly set +if ! npm dist-tag ls "$PACKAGE_NAME" | grep -q "$TAG: $VERSION"; then + echo "Failed to verify the deployment of version $VERSION with tag $TAG within the timeout period." + exit 1 +fi diff --git a/build_manifest.yml b/build_manifest.yml index afba6e3820f7..eb20879ecae8 100644 --- a/build_manifest.yml +++ b/build_manifest.yml @@ -263,8 +263,3 @@ docs: - noir-packages - l1-contracts - noir-projects - -yellow-paper: - buildDir: yellow-paper - rebuildPatterns: - - ^yellow-paper/ diff --git a/docs/docs/developers/contracts/compiling_contracts/how_to_compile_contract.md b/docs/docs/developers/contracts/compiling_contracts/how_to_compile_contract.md index 7d78818d4ff6..6135b4d8e1ae 100644 --- a/docs/docs/developers/contracts/compiling_contracts/how_to_compile_contract.md +++ b/docs/docs/developers/contracts/compiling_contracts/how_to_compile_contract.md @@ -24,10 +24,8 @@ This will output a JSON [artifact](./artifacts.md) for each contract in the proj You can use the code generator to autogenerate type-safe typescript classes for each of your contracts. These classes define type-safe methods for deploying and interacting with your contract based on their artifact. -To generate them, include a `--ts` option in the `codegen` command with a path to the target folder for the typescript files: - ```bash -aztec-cli codegen ./aztec-nargo/output/target/path -o src/artifacts --ts +aztec-cli codegen ./aztec-nargo/output/target/path -o src/artifacts ``` Below is typescript code generated from the [Token](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/noir-contracts/contracts/token_contract/src/main.nr) contract: @@ -119,94 +117,34 @@ Read more about interacting with contracts using `aztec.js` [here](../../getting An Aztec.nr contract can [call a function](../writing_contracts/functions/call_functions.md) in another contract via `context.call_private_function` or `context.call_public_function`. However, this requires manually assembling the function selector and manually serializing the arguments, which is not type-safe. -To make this easier, the compiler can generate contract interface structs that expose a convenience method for each function listed in a given contract artifact. These structs are intended to be used from another contract project that calls into the current one. For each contract, two interface structs are generated: one to be used from private functions with a `PrivateContext`, and one to be used from open functions with a `PublicContext`. - -To generate them, include a `--nr` option in the `codegen` command with a path to the target folder for the generated Aztec.nr interface files: - -```bash -aztec-cli codegen ./aztec-nargo/output/target/path -o ./path/to/output/folder --nr -``` +To make this easier, the compiler automatically generates interface structs that expose a convenience method for each function listed in a given contract artifact. These structs are intended to be used from another contract project that calls into the current one. -Below is an example interface, also generated from the [Token](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/noir-contracts/contracts/token_contract/src/main.nr) contract: +Below is an example of interface usage generated from the [Token](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/noir-contracts/contracts/token_contract/src/main.nr) contract, used from the [FPC](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr): ```rust -impl TokenPrivateContextInterface { - pub fn at(address: Field) -> Self { - Self { - address, - } - } - - pub fn burn( - self, - context: &mut PrivateContext, - from: FromBurnStruct, - amount: Field, - nonce: Field - ) -> [Field; RETURN_VALUES_LENGTH] { - let mut serialized_args = [0; 3]; - serialized_args[0] = from.address; - serialized_args[1] = amount; - serialized_args[2] = nonce; - - context.call_private_function(self.address, 0xd4fcc96e, serialized_args) - } - - - pub fn burn_public( - self, - context: &mut PrivateContext, - from: FromBurnPublicStruct, - amount: Field, - nonce: Field - ) { - let mut serialized_args = [0; 3]; - serialized_args[0] = from.address; - serialized_args[1] = amount; - serialized_args[2] = nonce; +contract FPC { - context.call_public_function(self.address, 0xb0e964d5, serialized_args) - } - ... - -} + ... -impl TokenPublicContextInterface { - pub fn at(address: Field) -> Self { - Self { - address, - } - } + use dep::token::Token; - pub fn burn_public( - self, - context: PublicContext, - from: FromBurnPublicStruct, - amount: Field, - nonce: Field - ) -> [Field; RETURN_VALUES_LENGTH] { - let mut serialized_args = [0; 3]; - serialized_args[0] = from.address; - serialized_args[1] = amount; - serialized_args[2] = nonce; - - context.call_public_function(self.address, 0xb0e964d5, serialized_args) - } + ... - pub fn mint_private( - self, - context: PublicContext, - amount: Field, - secret_hash: Field - ) -> [Field; RETURN_VALUES_LENGTH] { - let mut serialized_args = [0; 2]; - serialized_args[0] = amount; - serialized_args[1] = secret_hash; + #[aztec(private)] + fn fee_entrypoint_private(amount: Field, asset: AztecAddress, secret_hash: Field, nonce: Field) { + assert(asset == storage.other_asset.read_private()); + Token::at(asset).unshield(context.msg_sender(), context.this_address(), amount, nonce).call(&mut context); + FPC::at(context.this_address()).pay_fee_with_shielded_rebate(amount, asset, secret_hash).enqueue(&mut context); + } - context.call_public_function(self.address, 0x10763932, serialized_args) - } + #[aztec(private)] + fn fee_entrypoint_public(amount: Field, asset: AztecAddress, nonce: Field) { + FPC::at(context.this_address()).prepare_fee(context.msg_sender(), amount, asset, nonce).enqueue(&mut context); + FPC::at(context.this_address()).pay_fee(context.msg_sender(), amount, asset).enqueue(&mut context); + } + ... } ``` diff --git a/docs/docs/developers/contracts/deploying_contracts/how_to_deploy_contract.md b/docs/docs/developers/contracts/deploying_contracts/how_to_deploy_contract.md index 2ac74e787e27..dd646d383fba 100644 --- a/docs/docs/developers/contracts/deploying_contracts/how_to_deploy_contract.md +++ b/docs/docs/developers/contracts/deploying_contracts/how_to_deploy_contract.md @@ -40,7 +40,7 @@ aztec-nargo compile Generate the typescript class: ```bash -aztec-cli codegen ./aztec-nargo/output/target/path -o src/artifacts --ts +aztec-cli codegen ./aztec-nargo/output/target/path -o src/artifacts ``` This would create a typescript file like `Example.ts` in `./src/artifacts`. Read more on the [compiling page](../compiling_contracts/how_to_compile_contract.md). diff --git a/docs/docs/developers/contracts/references/storage/private_state.md b/docs/docs/developers/contracts/references/storage/private_state.md index dd82a21a02c6..6215902d3efa 100644 --- a/docs/docs/developers/contracts/references/storage/private_state.md +++ b/docs/docs/developers/contracts/references/storage/private_state.md @@ -240,7 +240,7 @@ Functionally similar to [`get_notes`](#get_notes), but executed unconstrained an #include_code view_notes /noir-projects/aztec-nr/value-note/src/balance_utils.nr rust -There's also a limit on the maximum number of notes that can be returned in one go. To find the current limit, refer to [this file](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr) and look for `MAX_NOTES_PER_PAGE`. +There's also a limit on the maximum number of notes that can be returned in one go. To find the current limit, refer to [this file](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/note/constants.nr) and look for `MAX_NOTES_PER_PAGE`. The key distinction is that this method is unconstrained. It does not perform a check to verify if the notes actually exist, which is something the [`get_notes`](#get_notes) method does under the hood. Therefore, it should only be used in an unconstrained contract function. diff --git a/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/implement_slow_updates.md b/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/implement_slow_updates.md index d738af37879d..6de1c8abae63 100644 --- a/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/implement_slow_updates.md +++ b/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/implement_slow_updates.md @@ -8,25 +8,19 @@ On this page you will learn how to implement a slow updates tree into your contr # How to implement a slow updates tree -1. Copy the _SlowTree.nr_ example and its dependencies, found [here](https://github.com/AztecProtocol/aztec-packages/tree/master/noir-projects/noir-contracts/contracts/slow_tree_contract). Replace the constants with whatever you like and deploy it to your sandbox -2. Copy the _SlowMap interface_ for easy interaction with your deployed SlowTree. Find it [here](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/interfaces.nr) -3. Import this interface into your contract - -#include_code interface noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr rust - -5. Store the SlowTree address in private storage as a FieldNote +1. Store the SlowTree address in private storage as a FieldNote #include_code constructor noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr rust -6. Store the SlowTree address in public storage and initialize an instance of SlowMap using this address +2. Store the SlowTree address in public storage and initialize an instance of SlowMap using this address #include_code write_slow_update_public noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr rust -7. Now you can read and update from private functions: +3. Now you can read and update from private functions: #include_code get_and_update_private noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr rust -8. Or from public functions: +4. Or from public functions: #include_code get_public noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr rust diff --git a/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md b/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md index 170981942d9a..4edc82d05375 100644 --- a/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md +++ b/docs/docs/developers/contracts/writing_contracts/historical_data/slow_updates_tree/main.md @@ -16,10 +16,6 @@ There are generally 4 main components involved to make it easier to use a slow u This is the primary smart contract that will use the slow updates tree. In the example we use a [token with blacklisting features](./implement_slow_updates.md#exploring-an-example-integration-through-a-tokenblacklist-smart-contract). -## Interface - -This interface of the slow updates tree contract allows your contract to interact with the Slow Updates Tree contract. It provides methods for reading and updating values in the tree in both public and private contexts. You can find it [here](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/interfaces.nr). - ## SlowTree.nr contract This is a smart contract developed by Aztec that establishes and manages a slow updates tree structure. It allows developers to access and interact with the tree, such as reading and updating data. diff --git a/docs/docs/developers/debugging/aztecnr-errors.md b/docs/docs/developers/debugging/aztecnr-errors.md index 5d5fd8053a90..67b6496612dd 100644 --- a/docs/docs/developers/debugging/aztecnr-errors.md +++ b/docs/docs/developers/debugging/aztecnr-errors.md @@ -67,7 +67,7 @@ This error occurs when your contract is trying to get a secret via the `get_secr This error might occur when you register an account only as a recipient and not as an account. To address the error, register the account by calling `server.registerAccount(...)`. -#### `Failed to solve brillig function, reason: explicit trap hit in brillig 'self._is_some` +#### `Failed to solve brillig function 'self._is_some` You may encounter this error when trying to send a transaction that is using an invalid contract. The contract may compile without errors and you only encounter this when sending the transaction. diff --git a/docs/docs/developers/getting_started/aztecnr-getting-started.md b/docs/docs/developers/getting_started/aztecnr-getting-started.md index ae8b1e83e23e..d7b9dd1eb108 100644 --- a/docs/docs/developers/getting_started/aztecnr-getting-started.md +++ b/docs/docs/developers/getting_started/aztecnr-getting-started.md @@ -147,7 +147,7 @@ This will compile the smart contract and create a `target` folder with a `.json` After compiling, you can generate a typescript class. In the same directory, run this: ```bash -aztec-cli codegen target -o src/artifacts --ts +aztec-cli codegen target -o src/artifacts ``` ### Deploy diff --git a/docs/docs/developers/tutorials/token_portal/minting_on_aztec.md b/docs/docs/developers/tutorials/token_portal/minting_on_aztec.md index 877a507122d0..0eb400f0acbf 100644 --- a/docs/docs/developers/tutorials/token_portal/minting_on_aztec.md +++ b/docs/docs/developers/tutorials/token_portal/minting_on_aztec.md @@ -12,13 +12,6 @@ In our `token-bridge` Aztec project in `aztec-contracts`, under `src` there is a #include_code token_bridge_storage_and_constructor /noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr rust -This imports Aztec-related dependencies and our helper file `token_interface.nr`. -(The code above will give errors right now - this is because we haven't implemented util and token_interface yet.) - -In `token_interface.nr`, add this: - -#include_code token_bridge_token_interface /noir-projects/noir-contracts/contracts/token_bridge_contract/src/token_interface.nr rust - ## Consume the L1 message In the previous step, we have moved our funds to the portal and created a L1->L2 message. Upon building the next rollup, the sequencer asks the inbox for any incoming messages and adds them to Aztec’s L1->L2 message tree, so an application on L2 can prove that the message exists and consumes it. diff --git a/docs/docs/developers/tutorials/token_portal/setup.md b/docs/docs/developers/tutorials/token_portal/setup.md index 1678df1f98e6..8eb45c6d4356 100644 --- a/docs/docs/developers/tutorials/token_portal/setup.md +++ b/docs/docs/developers/tutorials/token_portal/setup.md @@ -65,7 +65,7 @@ aztec = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_ token_portal_content_hash_lib = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="noir-projects/noir-contracts/contracts/token_portal_content_hash_lib" } ``` -We will also be writing some helper functions that should exist elsewhere so we don't overcomplicated our contract. In `src` create two more files - one called `util.nr` and one called `token_interface` - so your dir structure should now look like this: +We will also be writing some helper functions that should exist elsewhere so we don't overcomplicated our contract. In `src` create one more file called `util.nr` - so your dir structure should now look like this: ```tree aztec-contracts @@ -73,7 +73,6 @@ aztec-contracts ├── Nargo.toml ├── src ├── main.nr - ├── token_interface.nr ├── util.nr ``` diff --git a/docs/docs/developers/tutorials/token_portal/withdrawing_to_l1.md b/docs/docs/developers/tutorials/token_portal/withdrawing_to_l1.md index 4e2246e20fb5..524e106ef516 100644 --- a/docs/docs/developers/tutorials/token_portal/withdrawing_to_l1.md +++ b/docs/docs/developers/tutorials/token_portal/withdrawing_to_l1.md @@ -81,7 +81,7 @@ aztec-nargo compile And generate the TypeScript interface for the contract and add it to the test dir: ```bash -aztec-cli codegen target -o ../../src/test/fixtures --ts +aztec-cli codegen target -o ../../src/test/fixtures ``` This will create a TS interface in our `src/test` folder! diff --git a/docs/docs/developers/tutorials/uniswap/setup.md b/docs/docs/developers/tutorials/uniswap/setup.md index a80b63e734a2..ba86ecb73bec 100644 --- a/docs/docs/developers/tutorials/uniswap/setup.md +++ b/docs/docs/developers/tutorials/uniswap/setup.md @@ -50,6 +50,8 @@ Inside `uniswap/Nargo.toml` paste this in `[dependencies]`: [dependencies] aztec = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="noir-projects/aztec-nr/aztec" } authwit = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="noir-projects/aztec-nr/authwit"} +token = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="noir-projects/noir-contracts/token_contract" } +token_bridge = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="noir-projects/noir-contracts/token_bridge_contract" } ``` ## L2 contracts @@ -57,18 +59,9 @@ authwit = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#includ The `main.nr` will utilize a few helper functions that are outside the scope of this tutorial. Inside `uniswap/src` create two new files: ```bash -cd uniswap/src && touch util.nr && touch interfaces.nr +cd uniswap/src && touch util.nr ``` -Inside `interfaces.nr` paste this: - -#include_code interfaces noir-projects/noir-contracts/contracts/uniswap_contract/src/interfaces.nr rust - -This creates interfaces for the `Token` contract and `TokenBridge` contract - -- `Token` is a reference implementation for a token on Aztec. Here we just need two methods - [`transfer_public`](../writing_token_contract.md#transfer_public) and [`unshield()`](../writing_token_contract.md#unshield). -- The `TokenBridge` facilitates interactions with our [bridge contract](../token_portal/main.md). Here we just need its [`exit_to_l1_public`](../token_portal/withdrawing_to_l1.md) - ## Run Aztec sandbox You will need a running sandbox. diff --git a/docs/docs/developers/tutorials/uniswap/typescript_glue_code.md b/docs/docs/developers/tutorials/uniswap/typescript_glue_code.md index 805a92498268..2d5d04e4a1bf 100644 --- a/docs/docs/developers/tutorials/uniswap/typescript_glue_code.md +++ b/docs/docs/developers/tutorials/uniswap/typescript_glue_code.md @@ -36,7 +36,7 @@ aztec-nargo compile And then generate the typescript interface: ```bash -aztec-cli codegen ./target/ -o ../../../src/test/fixtures uniswap --ts +aztec-cli codegen ./target/ -o ../../../src/test/fixtures uniswap ``` This will create a TS interface in our `src/test` folder that will help us write our test. diff --git a/docs/docs/developers/tutorials/writing_private_voting_contract.md b/docs/docs/developers/tutorials/writing_private_voting_contract.md index 685b89a9412b..1178600c72ac 100644 --- a/docs/docs/developers/tutorials/writing_private_voting_contract.md +++ b/docs/docs/developers/tutorials/writing_private_voting_contract.md @@ -158,7 +158,7 @@ aztec-nargo compile This will create a new directory called `target` and a JSON artifact inside it. To optionally create a typescript interface, run: ```bash -aztec-cli codegen target -o src/artifacts --ts +aztec-cli codegen target -o src/artifacts ``` Once it is compiled you can [deploy](../contracts/deploying_contracts/how_to_deploy_contract.md) it to the sandbox. Ensure your [sandbox is running](../sandbox/references/sandbox-reference.md) and run this in the same dir as before: diff --git a/docs/docs/developers/tutorials/writing_token_contract.md b/docs/docs/developers/tutorials/writing_token_contract.md index a4f5926c5b50..a9b9e9423910 100644 --- a/docs/docs/developers/tutorials/writing_token_contract.md +++ b/docs/docs/developers/tutorials/writing_token_contract.md @@ -431,7 +431,7 @@ aztec-nargo compile Once your contract is compiled, optionally generate a typescript interface with the following command: ```bash -aztec-cli codegen target -o src/artifacts --ts +aztec-cli codegen target -o src/artifacts ``` ## Next Steps diff --git a/docs/docs/misc/migration_notes.md b/docs/docs/misc/migration_notes.md index 8f4f8b842174..7ccee0ee58f8 100644 --- a/docs/docs/misc/migration_notes.md +++ b/docs/docs/misc/migration_notes.md @@ -8,6 +8,53 @@ Aztec is in full-speed development. Literally every version breaks compatibility ## TBD +### [Aztec.nr] Contract interfaces + +It is now possible to import contracts on another contracts and use their automatic interfaces to perform calls. The interfaces have the same name as the contract, and are automatically exported. Parameters are automatically serialized (using the `Serialize` trait) and return values are automatically deserialized (using the `Deserialize` trait). Serialize and Deserialize methods have to conform to the standard ACVM serialization schema for the interface to work! + +1. Only fixed length types are supported +2. All numeric types become Fields +3. Strings become arrays of Fields, one per char +4. Arrays become arrays of Fields following rules 2 and 3 +5. Structs become arrays of Fields, with every item defined in the same order as they are in Noir code, following rules 2, 3, 4 and 5 (recursive) + +```diff +- context.call_public_function( +- storage.gas_token_address.read_private(), +- FunctionSelector::from_signature("pay_fee(Field)"), +- [42] +- ); +- +- context.call_public_function( +- storage.gas_token_address.read_private(), +- FunctionSelector::from_signature("pay_fee(Field)"), +- [42] +- ); +- +- let _ = context.call_private_function( +- storage.subscription_token_address.read_private(), +- FunctionSelector::from_signature("transfer((Field),(Field),Field,Field)"), +- [ +- context.msg_sender().to_field(), +- storage.subscription_recipient_address.read_private().to_field(), +- storage.subscription_price.read_private(), +- nonce +- ] +- ); ++ use dep::gas_token::GasToken; ++ use dep::token::Token; ++ ++ ... ++ // Public call from public land ++ GasToken::at(storage.gas_token_address.read_private()).pay_fee(42).call(&mut context); ++ // Public call from private land ++ GasToken::at(storage.gas_token_address.read_private()).pay_fee(42).enqueue(&mut context); ++ // Private call from private land ++ Token::at(asset).transfer(context.msg_sender(), storage.subscription_recipient_address.read_private(), amount, nonce).call(&mut context); +``` + +It is also possible to use these automatic interfaces from the local contract, and thus enqueue public calls from private without having to rely on low level `context` calls. + ### [Aztec.nr] Rename max block number setter The `request_max_block_number` function has been renamed to `set_tx_max_block_number` to better reflect that it is not a getter, and that the setting is transaction-wide. @@ -17,6 +64,21 @@ The `request_max_block_number` function has been renamed to `set_tx_max_block_nu + context.set_tx_max_block_number(value); ``` +### [Aztec.nr] Required gas limits for public-to-public calls + +When calling a public function from another public function using the `call_public_function` method, you must now specify how much gas you're allocating to the nested call. This will later allow you to limit the amount of gas consumed by the nested call, and handle any out of gas errors. + +Note that gas limits are not yet enforced. For now, it is suggested you use `dep::aztec::context::gas::GasOpts::default()` which will forward all available gas. + +```diff ++ use dep::aztec::context::gas::GasOpts; + +- context.call_public_function(target_contract, target_selector, args); ++ context.call_public_function(target_contract, target_selector, args, GasOpts::default()); +``` + +Note that this is not required when enqueuing a public function from a private one, since top-level enqueued public functions will always consume all gas available for the transaction, as it is not possible to handle any out-of-gas errors. + ## 0.33 ### [Aztec.nr] Storage struct annotation diff --git a/yellow-paper/docs/addresses-and-keys/address.md b/docs/docs/protocol-specs/addresses-and-keys/address.md similarity index 98% rename from yellow-paper/docs/addresses-and-keys/address.md rename to docs/docs/protocol-specs/addresses-and-keys/address.md index e2fc1a1acff6..5cd2e3ac20d4 100644 --- a/yellow-paper/docs/addresses-and-keys/address.md +++ b/docs/docs/protocol-specs/addresses-and-keys/address.md @@ -73,7 +73,7 @@ address_crh( } ``` -The `public_keys` array can vary depending on the format of keys used by the address, but it is suggested it includes the master keys defined in the [keys section](./keys.mdx). For example: +The `public_keys` array can vary depending on the format of keys used by the address, but it is suggested it includes the master keys defined in the [keys section](./keys.md). For example: ```rust let public_keys_hash: Field = poseidon2( diff --git a/yellow-paper/docs/addresses-and-keys/diversified-and-stealth.md b/docs/docs/protocol-specs/addresses-and-keys/diversified-and-stealth.md similarity index 95% rename from yellow-paper/docs/addresses-and-keys/diversified-and-stealth.md rename to docs/docs/protocol-specs/addresses-and-keys/diversified-and-stealth.md index f4fc8613f803..51a274e12b44 100644 --- a/yellow-paper/docs/addresses-and-keys/diversified-and-stealth.md +++ b/docs/docs/protocol-specs/addresses-and-keys/diversified-and-stealth.md @@ -2,7 +2,7 @@ title: Diversified and Stealth Accounts --- -The [keys specification](./keys.mdx) describes derivation mechanisms for diversified and stealth public keys. However, the protocol requires users to interact with addresses. +The [keys specification](./keys.md) describes derivation mechanisms for diversified and stealth public keys. However, the protocol requires users to interact with addresses. ## Computing Addresses diff --git a/yellow-paper/docs/addresses-and-keys/example-usage/diversified-and-stealth-keys.mdx b/docs/docs/protocol-specs/addresses-and-keys/example-usage/diversified-and-stealth-keys.md similarity index 96% rename from yellow-paper/docs/addresses-and-keys/example-usage/diversified-and-stealth-keys.mdx rename to docs/docs/protocol-specs/addresses-and-keys/example-usage/diversified-and-stealth-keys.md index b973e567ff5a..fed3329e8959 100644 --- a/yellow-paper/docs/addresses-and-keys/example-usage/diversified-and-stealth-keys.mdx +++ b/docs/docs/protocol-specs/addresses-and-keys/example-usage/diversified-and-stealth-keys.md @@ -1,8 +1,3 @@ - - -import LatexPreamble from "../0-keys-latex-preamble.md"; -; - ## Deriving diversified public keys A diversified public key can be derived from Alice's keys, to enhance Alice's transaction privacy. If Alice's counterparties' databases are compromised, it enables Alice to retain privacy from such leakages. Diversified public keys are used for generating diversified addresses. diff --git a/yellow-paper/docs/addresses-and-keys/example-usage/encrypt-and-tag.mdx b/docs/docs/protocol-specs/addresses-and-keys/example-usage/encrypt-and-tag.md similarity index 97% rename from yellow-paper/docs/addresses-and-keys/example-usage/encrypt-and-tag.mdx rename to docs/docs/protocol-specs/addresses-and-keys/example-usage/encrypt-and-tag.md index 92835a848e93..c25642d832fd 100644 --- a/yellow-paper/docs/addresses-and-keys/example-usage/encrypt-and-tag.mdx +++ b/docs/docs/protocol-specs/addresses-and-keys/example-usage/encrypt-and-tag.md @@ -1,8 +1,3 @@ - - -import LatexPreamble from "../0-keys-latex-preamble.md"; -; - ## Encrypt and tag an incoming message Bob wants to send Alice a private message, e.g. the contents of a note, which we'll refer to as the $\plaintext$. Bob and Alice are using a "tag hopping" scheme to help with note discovery. Let's assume they've already handshaked to establish a shared secret $\sharedsecret_{m,tagging}^{Bob \rightarrow Alice}$, from which a sequence of tags $\tagg_{m,i}^{Bob \rightarrow Alice}$ can be derived. diff --git a/yellow-paper/docs/addresses-and-keys/example-usage/nullifier.mdx b/docs/docs/protocol-specs/addresses-and-keys/example-usage/nullifier.md similarity index 86% rename from yellow-paper/docs/addresses-and-keys/example-usage/nullifier.mdx rename to docs/docs/protocol-specs/addresses-and-keys/example-usage/nullifier.md index 6504066b7ce0..5c3419d8fbec 100644 --- a/yellow-paper/docs/addresses-and-keys/example-usage/nullifier.mdx +++ b/docs/docs/protocol-specs/addresses-and-keys/example-usage/nullifier.md @@ -1,8 +1,3 @@ - - -import LatexPreamble from "../0-keys-latex-preamble.md"; -; - ## Deriving a nullifier within an app contract Let's assume a developer wants a nullifier of a note to be derived as: @@ -17,14 +12,14 @@ Here's example for how an app circuit _could_ constrain the nullifier key to be It's easiest to take a look at this first: -![Alt text](../images/addresses-and-keys/image.png) +![Alt text](/img/protocol-specs/addresses-and-keys/image.png) ### Within the app circuit Within the app, we can prove links between: -- the user's [$\nskapp$](../keys.mdx#app-siloed-nullifier-secret-key) and their [$\Nkapp$](../keys.mdx#app-siloed-nullifier-key); and between -- the user's [$\Npkm$](../keys.mdx#master-nullifier-public-key) and their [$\address$](../address.md). +- the user's [$\nskapp$](../keys.md#app-siloed-nullifier-secret-key) and their [$\Nkapp$](../keys.md#app-siloed-nullifier-key); and between +- the user's [$\Npkm$](../keys.md#master-nullifier-public-key) and their [$\address$](../address.md). The link that's missing is to prove that $\Npkm$ relates to $\nskapp$. To compute this missing link requires the $\nskm$, which MUST NOT be passed into an app circuit, and may only be passed into a kernel circuit. See the next ['Within the kernel circuit'](#within-the-kernel-circuit) section for details of this logic. diff --git a/yellow-paper/docs/addresses-and-keys/example-usage/tag-sequence-derivation.mdx b/docs/docs/protocol-specs/addresses-and-keys/example-usage/tag-sequence-derivation.md similarity index 96% rename from yellow-paper/docs/addresses-and-keys/example-usage/tag-sequence-derivation.mdx rename to docs/docs/protocol-specs/addresses-and-keys/example-usage/tag-sequence-derivation.md index 4919c665fce3..3484ec38560d 100644 --- a/yellow-paper/docs/addresses-and-keys/example-usage/tag-sequence-derivation.mdx +++ b/docs/docs/protocol-specs/addresses-and-keys/example-usage/tag-sequence-derivation.md @@ -1,8 +1,3 @@ - - -import LatexPreamble from "../0-keys-latex-preamble.md"; -; - # Handshaking for tag-hopping Deriving a sequence of tags for tag-hopping. diff --git a/yellow-paper/docs/addresses-and-keys/index.md b/docs/docs/protocol-specs/addresses-and-keys/index.md similarity index 85% rename from yellow-paper/docs/addresses-and-keys/index.md rename to docs/docs/protocol-specs/addresses-and-keys/index.md index bc0f6f27ab55..d9c2730d8fd0 100644 --- a/yellow-paper/docs/addresses-and-keys/index.md +++ b/docs/docs/protocol-specs/addresses-and-keys/index.md @@ -14,7 +14,7 @@ Keys in Aztec are used both for authorization and privacy. Authorization keys ar Privacy keys are used for note encryption, tagging, and nullifying. These are also not enforced by the protocol. However, for facilitating composability, the protocol enshrines a set of enshrined encryption and tagging mechanisms, that can be leveraged by applications as they interact with accounts. -The [requirements](./keys-requirements.md) section outlines the features that were sought when designing Aztec's addresses and keys. We then specify how [addresses](./address.md) are derived, as well as the default way in which [keys](./keys.mdx) will be derived. The [precompiles](./precompiles.md) section describes enshrined contract addresses, with implementations defined by the protocol, used for note encryption and tagging. +The [requirements](./keys-requirements.md) section outlines the features that were sought when designing Aztec's addresses and keys. We then specify how [addresses](./address.md) are derived, as well as the default way in which [keys](./keys.md) will be derived. The [precompiles](./precompiles.md) section describes enshrined contract addresses, with implementations defined by the protocol, used for note encryption and tagging. Last, the [diversified and stealth accounts](./diversified-and-stealth.md) sections describe application-level recommendations for diversified and stealth accounts. diff --git a/yellow-paper/docs/addresses-and-keys/keys-requirements.md b/docs/docs/protocol-specs/addresses-and-keys/keys-requirements.md similarity index 100% rename from yellow-paper/docs/addresses-and-keys/keys-requirements.md rename to docs/docs/protocol-specs/addresses-and-keys/keys-requirements.md diff --git a/yellow-paper/docs/addresses-and-keys/keys.mdx b/docs/docs/protocol-specs/addresses-and-keys/keys.md similarity index 99% rename from yellow-paper/docs/addresses-and-keys/keys.mdx rename to docs/docs/protocol-specs/addresses-and-keys/keys.md index 03eb55d15441..3e275e60dd73 100644 --- a/yellow-paper/docs/addresses-and-keys/keys.mdx +++ b/docs/docs/protocol-specs/addresses-and-keys/keys.md @@ -7,9 +7,6 @@ description: Specification for default privacy keys format and derivation, and n -import LatexPreamble from "./0-keys-latex-preamble.md"; -; - ## Cheat Sheet The protocol does not enforce the usage of any of the following keys, and does not enforce the keys to conform to a particular length or algorithm. Users are expected to pick a set of keys valid for the encryption and tagging precompile they choose for their account. @@ -51,7 +48,7 @@ The protocol does not enforce the usage of any of the following keys, and does n Diagram is out of date vs the content on this page ::: -![Alt text](images/addresses-and-keys/image-5.png) + The red boxes are uncertainties, which are explained later in this doc. diff --git a/yellow-paper/docs/addresses-and-keys/precompiles.md b/docs/docs/protocol-specs/addresses-and-keys/precompiles.md similarity index 100% rename from yellow-paper/docs/addresses-and-keys/precompiles.md rename to docs/docs/protocol-specs/addresses-and-keys/precompiles.md diff --git a/yellow-paper/docs/bytecode/index.md b/docs/docs/protocol-specs/bytecode/index.md similarity index 90% rename from yellow-paper/docs/bytecode/index.md rename to docs/docs/protocol-specs/bytecode/index.md index a7484820b142..4f54d240c5f0 100644 --- a/yellow-paper/docs/bytecode/index.md +++ b/docs/docs/protocol-specs/bytecode/index.md @@ -42,7 +42,7 @@ There are three different (but related) bytecode standards that are used in Azte # AVM Bytecode -The AVM bytecode is the compilation target of the public functions of a contract. It's specified in the [AVM section](../public-vm/instruction-set). It allows control flow and uses a flat memory model which tracks bit sizes of values stored in memory via tagging of memory indexes. Sequencers run the AVM bytecode of the public functions of a contract using the AVM and prove the correct execution of it. +The AVM bytecode is the compilation target of the public functions of a contract. It's specified in the [AVM section](../public-vm/instruction-set.mdx). It allows control flow and uses a flat memory model which tracks bit sizes of values stored in memory via tagging of memory indexes. Sequencers run the AVM bytecode of the public functions of a contract using the AVM and prove the correct execution of it. # Brillig Bytecode @@ -52,7 +52,7 @@ Brillig bytecode will be very similar to AVM bytecode. While AVM bytecode is spe Oracles allow nondeterminism during the execution of a given function, allowing the simulator entity to choose the value that an oracle will return during the simulation process. Oracles are heavily used by aztec.nr to fetch data during simulation of private and unconstrained functions, such as fetching notes. They are also used to notify the simulator about events arising during execution, such as a nullified note so that it's not offered again during the simulation. -However, AVM bytecode doesn't allow arbitrary oracles, any nondeterminism introduced is done in a way that the protocol can ensure that the simulator entity (the sequencer) cannot manipulate the result of an oracle. As such, when transforming brillig bytecode to AVM bytecode, all the oracles are replaced by the specific opcodes that the AVM supports for nondeterminism, like [TIMESTAMP](../public-vm/instruction-set#isa-section-timestamp), [ADDRESS](../public-vm/instruction-set#isa-section-address), etc. Any opcode that requires the simulator entity to provide data external to the AVM memory is non-deterministic. +However, AVM bytecode doesn't allow arbitrary oracles, any nondeterminism introduced is done in a way that the protocol can ensure that the simulator entity (the sequencer) cannot manipulate the result of an oracle. As such, when transforming brillig bytecode to AVM bytecode, all the oracles are replaced by the specific opcodes that the AVM supports for nondeterminism, like [TIMESTAMP](../public-vm/instruction-set.mdx#isa-section-timestamp), [ADDRESS](../public-vm/instruction-set.mdx#isa-section-address), etc. Any opcode that requires the simulator entity to provide data external to the AVM memory is non-deterministic. The current implementation of Brillig can be found [in the noir repository](https://github.com/noir-lang/noir/blob/master/acvm-repo/brillig/src/opcodes.rs#L60). It's actively being changed to become "AVM bytecode without arbitrary oracles" and right now the differences are handled by a transpiler. @@ -73,7 +73,7 @@ This implies that a block of ACIR bytecode can represent more than one program, ## Compiling a contract -When a contract is compiled, an artifact will be generated. This artifact needs to be hashed in a specific manner [detailed in the deployment section](../contract-deployment/classes#artifact-hash) for publishing. +When a contract is compiled, an artifact will be generated. This artifact needs to be hashed in a specific manner [detailed in the deployment section](../contract-deployment/classes.md#artifact-hash) for publishing. The exact form of the artifact is not specified by the protocol, but it needs at least the following information: @@ -148,19 +148,19 @@ If the function is public, the entry will be its ABI. If the function is private ### Bytecode in the artifact -The protocol mandates that public bytecode needs to be published to a data availability solution, since the sequencers need to have the data available to run the public functions. Also, it needs to use an encoding that is friendly to the public VM, such as the one specified in the [AVM section](../public-vm/bytecode-validation-circuit). +The protocol mandates that public bytecode needs to be published to a data availability solution, since the sequencers need to have the data available to run the public functions. Also, it needs to use an encoding that is friendly to the public VM, such as the one specified in the [AVM section](../public-vm/bytecode-validation-circuit.md). -The bytecode of private and unconstrained functions doesn't need to be published, instead, users that desire to use a given contract can add the artifact to their PXE before interacting with it. Publishing it is [supported but not required](../contract-deployment/classes/#broadcast) by the protocol. However, the verification key of a private function is hashed into the function's leaf of the contract's function tree, so the user can prove to the protocol that he executed the function correctly. Also, contract classes contain an [artifact hash](../contract-deployment/classes#artifact-hash) so the PXE can verify that the artifact corresponds with the contract class. +The bytecode of private and unconstrained functions doesn't need to be published, instead, users that desire to use a given contract can add the artifact to their PXE before interacting with it. Publishing it is [supported but not required](../contract-deployment/classes.md#broadcast) by the protocol. However, the verification key of a private function is hashed into the function's leaf of the contract's function tree, so the user can prove to the protocol that he executed the function correctly. Also, contract classes contain an [artifact hash](../contract-deployment/classes.md#artifact-hash) so the PXE can verify that the artifact corresponds with the contract class. The encoding of private and unconstrained functions is not specified by the protocol, but it's recommended to follow [the encoding](https://github.com/noir-lang/noir/blob/master/acvm-repo/acir/src/circuit/mod.rs#L157) that Barretenberg and the ACVM share that is serialization using bincode and gzip for compression. -This implies that the encoding of private and unconstrained functions does not need to be friendly to circuits, since when publishing it the protocol only sees a [generic array of field elements](../contract-deployment/classes#broadcast). +This implies that the encoding of private and unconstrained functions does not need to be friendly to circuits, since when publishing it the protocol only sees a [generic array of field elements](../contract-deployment/classes.md#broadcast). ## Executing a private function When executing a private function, its ACIR bytecode will be executed by the PXE using the ACVM. The ACVM will generate the witness of the execution. The proving system can be used to generate a proof of the correctness of the witness. -The fact that the correct function was executed is checked by the protocol by verifying that the [contract class ID](../contract-deployment/classes#class-identifier) contains one leaf in the function tree with this selector and the verification key of the function. +The fact that the correct function was executed is checked by the protocol by verifying that the [contract class ID](../contract-deployment/classes.md#class-identifier) contains one leaf in the function tree with this selector and the verification key of the function. ## Executing an unconstrained function @@ -170,4 +170,4 @@ When executing an unconstrained function, its Brillig bytecode will be executed When executing a public function, its AVM bytecode will be executed by the sequencer with the specified selector and arguments. The sequencer will generate a public VM proof of the correct execution of the AVM bytecode. -The fact that the correct bytecode was executed is checked by the protocol by verifying that the [contract class ID](../contract-deployment/classes#class-identifier) contains the [commitment](../public-vm/bytecode-validation-circuit#committed-representation) to the bytecode used. +The fact that the correct bytecode was executed is checked by the protocol by verifying that the [contract class ID](../contract-deployment/classes.md#class-identifier) contains the [commitment](../public-vm/bytecode-validation-circuit.md#committed-representation) to the bytecode used. diff --git a/yellow-paper/docs/calls/batched-calls.md b/docs/docs/protocol-specs/calls/batched-calls.md similarity index 100% rename from yellow-paper/docs/calls/batched-calls.md rename to docs/docs/protocol-specs/calls/batched-calls.md diff --git a/yellow-paper/docs/calls/delegate-calls.md b/docs/docs/protocol-specs/calls/delegate-calls.md similarity index 100% rename from yellow-paper/docs/calls/delegate-calls.md rename to docs/docs/protocol-specs/calls/delegate-calls.md diff --git a/yellow-paper/docs/calls/enqueued-calls.md b/docs/docs/protocol-specs/calls/enqueued-calls.md similarity index 100% rename from yellow-paper/docs/calls/enqueued-calls.md rename to docs/docs/protocol-specs/calls/enqueued-calls.md diff --git a/yellow-paper/docs/calls/index.md b/docs/docs/protocol-specs/calls/index.md similarity index 100% rename from yellow-paper/docs/calls/index.md rename to docs/docs/protocol-specs/calls/index.md diff --git a/yellow-paper/docs/calls/public-private-messaging.md b/docs/docs/protocol-specs/calls/public-private-messaging.md similarity index 98% rename from yellow-paper/docs/calls/public-private-messaging.md rename to docs/docs/protocol-specs/calls/public-private-messaging.md index 9d8e164625c7..edbe6720dce9 100644 --- a/yellow-paper/docs/calls/public-private-messaging.md +++ b/docs/docs/protocol-specs/calls/public-private-messaging.md @@ -81,4 +81,4 @@ To elaborate, a public function may not have read access to encrypted private st In the picture below, it is worth noting that all data reads performed by private functions are historical in nature, and that private functions are not capable of modifying public storage. Conversely, public functions have the capacity to manipulate private storage (e.g., inserting new note hashes, potentially as part of transferring funds from the public domain to the private domain). -![Public - Private Messaging](./images/calls/pub_pvt_messaging.png) +![Public - Private Messaging](/img/protocol-specs/calls/pub_pvt_messaging.png) diff --git a/yellow-paper/docs/calls/static-calls.md b/docs/docs/protocol-specs/calls/static-calls.md similarity index 100% rename from yellow-paper/docs/calls/static-calls.md rename to docs/docs/protocol-specs/calls/static-calls.md diff --git a/yellow-paper/docs/calls/sync-calls.md b/docs/docs/protocol-specs/calls/sync-calls.md similarity index 100% rename from yellow-paper/docs/calls/sync-calls.md rename to docs/docs/protocol-specs/calls/sync-calls.md diff --git a/yellow-paper/docs/calls/unconstrained-calls.md b/docs/docs/protocol-specs/calls/unconstrained-calls.md similarity index 100% rename from yellow-paper/docs/calls/unconstrained-calls.md rename to docs/docs/protocol-specs/calls/unconstrained-calls.md diff --git a/yellow-paper/docs/circuits/high-level-topology.md b/docs/docs/protocol-specs/circuits/high-level-topology.md similarity index 95% rename from yellow-paper/docs/circuits/high-level-topology.md rename to docs/docs/protocol-specs/circuits/high-level-topology.md index a25e9b5007dc..43f00cb05ea1 100644 --- a/yellow-paper/docs/circuits/high-level-topology.md +++ b/docs/docs/protocol-specs/circuits/high-level-topology.md @@ -9,7 +9,7 @@ Once all functions in a transaction are executed, the accumulated data is output To illustrate, consider a transaction involving the following functions, where circles depict private functions, and squares denote public functions: :::info -A note for Aztec protocol developers: In this yellow paper, the order in which the kernel circuit processes calls is different from previous literature, and is different from the current implementation (as at January 2024). +A note for Aztec protocol developers: In this protocol spec, the order in which the kernel circuit processes calls is different from previous literature, and is different from the current implementation (as at January 2024). ::: + diff --git a/yellow-paper/docs/circuits/private-kernel-inner.mdx b/docs/docs/protocol-specs/circuits/private-kernel-inner.mdx similarity index 97% rename from yellow-paper/docs/circuits/private-kernel-inner.mdx rename to docs/docs/protocol-specs/circuits/private-kernel-inner.mdx index 1f13b5f3b5c1..acc3c2495a01 100644 --- a/yellow-paper/docs/circuits/private-kernel-inner.mdx +++ b/docs/docs/protocol-specs/circuits/private-kernel-inner.mdx @@ -1,6 +1,6 @@ # Private Kernel Circuit - Inner - + ## Requirements @@ -147,9 +147,11 @@ class TransactionRequest { function_data: FunctionData args_hash: field tx_context: TransactionContext + gas_settings: GasSettings } TransactionRequest *-- FunctionData: function_data TransactionRequest *-- TransactionContext: tx_context +TransactionRequest *-- GasSettings: gas_settings TransactionRequest ..> ConstantData: tx_context @@ -224,6 +226,19 @@ class FunctionData { function_type: private|public } +class GasSettings { + da.gas_limit: u32 + da.teardown_gas_limit: u32 + da.max_fee_per_gas: Fr + l1.gas_limit: u32 + l1.teardown_gas_limit: u32 + l1.max_fee_per_gas: Fr + l2.gas_limit: u32 + l2.teardown_gas_limit: u32 + l2.max_fee_per_gas: Fr + inclusion_fee: Fr +} + class PrivateFunctionPublicInputs { call_context: CallContext args_hash: field @@ -276,6 +291,9 @@ class CallContext { portal_contract_address: AztecAddress is_delegate_call: bool is_static_call: bool + gas_left: Gas + gas_settings: GasSettings + transaction_fee: field } CallContext ..> CallerContext : call_context diff --git a/yellow-paper/docs/circuits/private-kernel-reset.md b/docs/docs/protocol-specs/circuits/private-kernel-reset.md similarity index 100% rename from yellow-paper/docs/circuits/private-kernel-reset.md rename to docs/docs/protocol-specs/circuits/private-kernel-reset.md diff --git a/yellow-paper/docs/circuits/private-kernel-tail.md b/docs/docs/protocol-specs/circuits/private-kernel-tail.md similarity index 100% rename from yellow-paper/docs/circuits/private-kernel-tail.md rename to docs/docs/protocol-specs/circuits/private-kernel-tail.md diff --git a/yellow-paper/docs/circuits/public-kernel-initial.md b/docs/docs/protocol-specs/circuits/public-kernel-initial.md similarity index 100% rename from yellow-paper/docs/circuits/public-kernel-initial.md rename to docs/docs/protocol-specs/circuits/public-kernel-initial.md diff --git a/yellow-paper/docs/circuits/public-kernel-inner.md b/docs/docs/protocol-specs/circuits/public-kernel-inner.md similarity index 100% rename from yellow-paper/docs/circuits/public-kernel-inner.md rename to docs/docs/protocol-specs/circuits/public-kernel-inner.md diff --git a/yellow-paper/docs/circuits/public-kernel-tail.md b/docs/docs/protocol-specs/circuits/public-kernel-tail.md similarity index 100% rename from yellow-paper/docs/circuits/public-kernel-tail.md rename to docs/docs/protocol-specs/circuits/public-kernel-tail.md diff --git a/yellow-paper/docs/constants.md b/docs/docs/protocol-specs/constants.md similarity index 100% rename from yellow-paper/docs/constants.md rename to docs/docs/protocol-specs/constants.md diff --git a/yellow-paper/docs/contract-deployment/classes.md b/docs/docs/protocol-specs/contract-deployment/classes.md similarity index 100% rename from yellow-paper/docs/contract-deployment/classes.md rename to docs/docs/protocol-specs/contract-deployment/classes.md diff --git a/yellow-paper/docs/contract-deployment/index.md b/docs/docs/protocol-specs/contract-deployment/index.md similarity index 100% rename from yellow-paper/docs/contract-deployment/index.md rename to docs/docs/protocol-specs/contract-deployment/index.md diff --git a/yellow-paper/docs/contract-deployment/instances.md b/docs/docs/protocol-specs/contract-deployment/instances.md similarity index 100% rename from yellow-paper/docs/contract-deployment/instances.md rename to docs/docs/protocol-specs/contract-deployment/instances.md diff --git a/yellow-paper/docs/cryptography/hashing/hashing.md b/docs/docs/protocol-specs/cryptography/hashing/hashing.md similarity index 92% rename from yellow-paper/docs/cryptography/hashing/hashing.md rename to docs/docs/protocol-specs/cryptography/hashing/hashing.md index d720c250cc96..a3e4cb5f5e73 100644 --- a/yellow-paper/docs/cryptography/hashing/hashing.md +++ b/docs/docs/protocol-specs/cryptography/hashing/hashing.md @@ -24,6 +24,6 @@ Pseudo-randomness is required in cases such as: - Fiat-Shamir challenge generation. - Expanding a random seed to generate additional randomness. - - See the derivation of [master secret keys](../../addresses-and-keys/keys.mdx#master-keys). + - See the derivation of [master secret keys](../../addresses-and-keys/keys.md#master-keys). - Deriving a nullifier, and siloing a nullifier. - - See [deriving a nullifier](../../addresses-and-keys/keys.mdx#deriving-a-nullifier-within-an-app-contract). + - See [deriving a nullifier](../../addresses-and-keys/keys.md#deriving-a-nullifier-within-an-app-contract). diff --git a/yellow-paper/docs/cryptography/hashing/pedersen.md b/docs/docs/protocol-specs/cryptography/hashing/pedersen.md similarity index 100% rename from yellow-paper/docs/cryptography/hashing/pedersen.md rename to docs/docs/protocol-specs/cryptography/hashing/pedersen.md diff --git a/yellow-paper/docs/cryptography/hashing/poseidon2.md b/docs/docs/protocol-specs/cryptography/hashing/poseidon2.md similarity index 100% rename from yellow-paper/docs/cryptography/hashing/poseidon2.md rename to docs/docs/protocol-specs/cryptography/hashing/poseidon2.md diff --git a/yellow-paper/docs/cryptography/index.md b/docs/docs/protocol-specs/cryptography/index.md similarity index 100% rename from yellow-paper/docs/cryptography/index.md rename to docs/docs/protocol-specs/cryptography/index.md diff --git a/yellow-paper/docs/cryptography/merkle-trees.md b/docs/docs/protocol-specs/cryptography/merkle-trees.md similarity index 100% rename from yellow-paper/docs/cryptography/merkle-trees.md rename to docs/docs/protocol-specs/cryptography/merkle-trees.md diff --git a/yellow-paper/docs/cryptography/proving-system/data-bus.md b/docs/docs/protocol-specs/cryptography/proving-system/data-bus.md similarity index 100% rename from yellow-paper/docs/cryptography/proving-system/data-bus.md rename to docs/docs/protocol-specs/cryptography/proving-system/data-bus.md diff --git a/yellow-paper/docs/cryptography/proving-system/overview.md b/docs/docs/protocol-specs/cryptography/proving-system/overview.md similarity index 98% rename from yellow-paper/docs/cryptography/proving-system/overview.md rename to docs/docs/protocol-specs/cryptography/proving-system/overview.md index f7f786a257e8..c76a01969d09 100644 --- a/yellow-paper/docs/cryptography/proving-system/overview.md +++ b/docs/docs/protocol-specs/cryptography/proving-system/overview.md @@ -62,7 +62,7 @@ The "Fold" Prover/Verifier validates that `k` instances of a defined relation (i #### Protogalaxy Decider -The "Decider" Prover/Verifier validate whether an accumulator instance correctly satisfies the accumulator relation. The accumulator being satisfiable inductively shows that all instances that have been folded were satisfied as well. (additional protocol checks are required to reason about _which_ instances have been folded into the accumulator. See the [IVC specification](https://hackmd.io/h0yTcOHiQWeeTXnxTQhTNQ?view) for more information. (note to zac: put this in the yellow paper!) +The "Decider" Prover/Verifier validate whether an accumulator instance correctly satisfies the accumulator relation. The accumulator being satisfiable inductively shows that all instances that have been folded were satisfied as well. (additional protocol checks are required to reason about _which_ instances have been folded into the accumulator. See the [IVC specification](https://hackmd.io/h0yTcOHiQWeeTXnxTQhTNQ?view) for more information. (note to zac: put this in the protocol specs!) ## Goblin Plonk @@ -122,4 +122,4 @@ To batch-verify multiple opening proofs, we use the technique articulated in the The following block diagrams describe the components used by the client-side and server-side Provers when computing client proofs and rollup proofs respectively. -![proof-system-components](../images/proof-system-components.png) +![proof-system-components](/img/protocol-specs/cryptography/proof-system-components.png) diff --git a/yellow-paper/docs/cryptography/proving-system/performance-targets.md b/docs/docs/protocol-specs/cryptography/proving-system/performance-targets.md similarity index 100% rename from yellow-paper/docs/cryptography/proving-system/performance-targets.md rename to docs/docs/protocol-specs/cryptography/proving-system/performance-targets.md diff --git a/yellow-paper/docs/data-publication-and-availability/index.md b/docs/docs/protocol-specs/data-publication-and-availability/index.md similarity index 100% rename from yellow-paper/docs/data-publication-and-availability/index.md rename to docs/docs/protocol-specs/data-publication-and-availability/index.md diff --git a/yellow-paper/docs/data-publication-and-availability/overview.md b/docs/docs/protocol-specs/data-publication-and-availability/overview.md similarity index 100% rename from yellow-paper/docs/data-publication-and-availability/overview.md rename to docs/docs/protocol-specs/data-publication-and-availability/overview.md diff --git a/yellow-paper/docs/data-publication-and-availability/published-data.md b/docs/docs/protocol-specs/data-publication-and-availability/published-data.md similarity index 100% rename from yellow-paper/docs/data-publication-and-availability/published-data.md rename to docs/docs/protocol-specs/data-publication-and-availability/published-data.md diff --git a/yellow-paper/docs/decentralization/actors.md b/docs/docs/protocol-specs/decentralization/actors.md similarity index 100% rename from yellow-paper/docs/decentralization/actors.md rename to docs/docs/protocol-specs/decentralization/actors.md diff --git a/yellow-paper/docs/decentralization/block-production.md b/docs/docs/protocol-specs/decentralization/block-production.md similarity index 99% rename from yellow-paper/docs/decentralization/block-production.md rename to docs/docs/protocol-specs/decentralization/block-production.md index f554c304865e..43731b8d14f0 100644 --- a/yellow-paper/docs/decentralization/block-production.md +++ b/docs/docs/protocol-specs/decentralization/block-production.md @@ -115,7 +115,7 @@ Anyone ->> Network: eligible as a sequencer - get rid of "pre-confirmed" ::: -![Governance Summary Image](./images/Aztec-Block-Production-1.png) +![Governance Summary Image](/img/protocol-specs/decentralization/Aztec-Block-Production-1.png) Every staked sequencers participate in the following phases, comprising an Aztec slot: @@ -275,7 +275,7 @@ It is likely that this proving ecosystem will emerge around a [flashbots mev-boo Specifically, Proof boost is expected to be open source software sequencers can optionally run alongside their clients that will facilitate a negotiation for the rights to prove this block, therefore earning block rewards in the form of the native protocol token. After the negotiation, the sequencer will commit to an address, and that address will need to put up an economic commitment (deposit) that will be slashed in the event that the block's proofs are not produced within the alloted timeframe. -![image](./images/Aztec-Block-Production-3.png) +![image](/img/protocol-specs/decentralization/Aztec-Block-Production-3.png) Initially it's expected that the negotiations and commitment could be facilitated by a trusted relay, similar to L1 block building, but options such as onchain proving pools are under consideration. Due to the out of protocol nature of [Sidecar](https://forum.aztec.network/t/proposal-prover-coordination-sidecar/2428), these designs can be iterated and improved upon outside the scope of other Aztec related governance or upgrades - as long as they maintain compatibility with the currently utilized proving system(s). Eventually, any upgrade or governance mechanism may choose to enshrine a specific well adopted proving protocol, if it makes sense to do so. diff --git a/yellow-paper/docs/decentralization/governance.md b/docs/docs/protocol-specs/decentralization/governance.md similarity index 97% rename from yellow-paper/docs/decentralization/governance.md rename to docs/docs/protocol-specs/decentralization/governance.md index 249b3149edf1..ee7208b76f93 100644 --- a/yellow-paper/docs/decentralization/governance.md +++ b/docs/docs/protocol-specs/decentralization/governance.md @@ -12,13 +12,13 @@ These instances may choose to be immutable themselves, or have governance that e The version registry will keep track of all historical versions of Aztec & provide them with incentives proportionate to their current stake. Additionally the governance contract will point to what the _current canonical_ version of Aztec is, particularly relevant for 3rd parties to follow, such as centralized exchanges, or portals that wish to follow Aztec governance. -![Governance Summary Image](./images/Aztec-Governance-Summary-1.png) +![Governance Summary Image](/img/protocol-specs/decentralization/Aztec-Governance-Summary-1.png) ## Rewards We propose introducing a governance "version registry" which keeps track of a) which deployments of Aztec have been canonical, and b) which instances currently have tokens staked to them, specifically in order to issue a consistent, single new token in the form of _incentives_ or "rollup/block rewards". -![Rewards Summary Image](./images/Aztec-Governance-Summary-2.png) +![Rewards Summary Image](/img/protocol-specs/decentralization/Aztec-Governance-Summary-2.png) Given that deployments may be immutable, it is necessary to ensure that there are operators, i.e., sequencers & provers, running the infrastructure for a given deployment as long as users are interested in it. Therefore we suggest a model where all previous canonical instances of Aztec are rewarded pro-rata to their current proportion of stake. @@ -35,11 +35,11 @@ Upon initial deployment, there will be an immutable set of governance contracts The initial instance will be called "Aztec v0" and (the current thinking is that v0) will not include the ability to process user transactions. Sequencers can register for Fernet's sequencer selection algorithm by staking tokens to that particular instance, and practice proposing blocks on mainnet prior to deciding to "go live" with v1, which _does_ enable the processing of user transactions. This instance would then _"restake"_ these tokens within the governance contract, to have a voting weight equal to the amount of tokens staked by its sequencer set. This is in order to ensure that the sequencer selection algorithm is working properly and the community of operators themselves can decide what happens to the network next, i.e., if it's ready to actually "go live" with transactions. It will also serve as a production readiness test of the upgradeability. In the event that these v0 tests are unable to be successfully completed as expected, the community (with potential foundation approval) may need to redeploy and try again. -![Initial Deployment Image](./images/Aztec-Governance-Summary-3.png) +![Initial Deployment Image](/img/protocol-specs/decentralization/Aztec-Governance-Summary-3.png) The ability to upgrade to v1 is articulated below, and should follow a "happy path" upgrade where a majority of the v0 sequencer set must agree to upgrade by voting during their block proposals, similar to what was articulated in [the empire stakes back](https://forum.aztec.network/t/upgrade-proposal-the-empire-stakes-back/626). Additionally, token holders can directly participate in the vote, or choose to delegate a vote with the weight of their tokens to another address, including the v0 rollup. -![Version 1 Deployment Image](./images/Aztec-Governance-Summary-4.png) +![Version 1 Deployment Image](/img/protocol-specs/decentralization/Aztec-Governance-Summary-4.png) ## Proposing a new version @@ -224,7 +224,7 @@ Sequencers ->> Next Rollup: Proposing new blocks here! Emergency mode is proposed to be introduced to the initial instance "v0" or "v1" of Aztec, whatever the first instance or deployment is. Emergency mode **will not be included as part of the canonical governance contracts or registry**. If future deployments wish to have a similar security council, they can choose to do so. In this design, the current rollup can determine the timelock period as articulated above, within some predefined constraints, e.g., 3-30 days. Explicitly, the current rollup can give a security council the ability to define what this timelock period may be, and in the case of a potential vulnerability or otherwise, may be well within it's rights to choose the smallest value defined by the immutable governance contract to ensure that the network is able to recover and come back online as quickly as possible. -![Emergency Mode Image](./images/Aztec-Governance-Summary-4.png) +![Emergency Mode Image](/img/protocol-specs/decentralization/Aztec-Governance-Summary-4.png) ### Unpausing by default diff --git a/yellow-paper/docs/decentralization/p2p-network.md b/docs/docs/protocol-specs/decentralization/p2p-network.md similarity index 91% rename from yellow-paper/docs/decentralization/p2p-network.md rename to docs/docs/protocol-specs/decentralization/p2p-network.md index 69e2206e7eb5..62c1bbe4c7f2 100644 --- a/yellow-paper/docs/decentralization/p2p-network.md +++ b/docs/docs/protocol-specs/decentralization/p2p-network.md @@ -29,7 +29,7 @@ Anyone can operate an instance of the Aztec Node configured to serve their needs Client PXEs will interact with instances of the Aztec Node via it's JSON RPC interface. -![P2P Network](./images/network.png) +![P2P Network](/img/protocol-specs/decentralization/network.png) ### Transaction Size @@ -40,7 +40,6 @@ Client PXEs will interact with instances of the Aztec Node via it's JSON RPC int | Public Inputs, Public Calls and Emitted Logs | ~8KB | | Private Kernel Proof | ~32KB | - ### Sequencer-to-Prover Communication Proving is an out-of-protocol activity. The nature of the communication between sequencers and provers will depend entirely on the prover/s selected by the sequencer. Provers may choose to run their own Transaction Pool Node infrastructure so that they are prepared for generating proofs and don't need to receive this data out-of-band. @@ -82,11 +81,11 @@ The underlying transport for DiscV5 communication is UDP. Whilst UDP is not reli ##### Bootstrapping -When a node wishes to join the network for the first time. It needs to locate at least 1 initial peer in order to 'discover' other nodes. This role is performed by known public 'bootnodes'. Bootnodes may not be full network participants, they may simply be entrypoints containing well populated routing tables for nodes to query. +When a node wishes to join the network for the first time. It needs to locate at least 1 initial peer in order to 'discover' other nodes. This role is performed by known public 'bootnodes'. Bootnodes may not be full network participants, they may simply be entrypoints containing well populated routing tables for nodes to query. ##### Topics -Topics are part of the DiscV5 specification, though the spec is as yet unfinished and implementations do not yet exist. The intention of topics is for the Ethereum P2P network to efficiently support any number of applications under the same discovery scheme. To date, many other applications use Ethereum's discovery network but the only way to 'discover' other nodes for the same application is to query nodes at random and interrogate them. Topics will allow this to be done more efficiently with nodes being able to 'advertise' themselves as supporting specific applications across the network. +Topics are part of the DiscV5 specification, though the spec is as yet unfinished and implementations do not yet exist. The intention of topics is for the Ethereum P2P network to efficiently support any number of applications under the same discovery scheme. To date, many other applications use Ethereum's discovery network but the only way to 'discover' other nodes for the same application is to query nodes at random and interrogate them. Topics will allow this to be done more efficiently with nodes being able to 'advertise' themselves as supporting specific applications across the network. ##### DiscV5 on Aztec @@ -100,17 +99,16 @@ Using Ethereum's DiscV5 network will have significant benefits for Aztec. Networ The node record for an Aztec node will contain the following key/value pairs. The network endpoints don't all need to be specified but nodes will require at least one ip address and port. The public key is required to verify the signature included with the node record. The id is the identity scheme with "v4" being that currently used by Ethereum. - -| key | value | -| -------- | -------- | -| id | "v4" | -| secp256k1 | The node's public key | -| ip | ipv4 address | -| tcp | tcp port | -| ip6 | ipv6 address | -| tcp6 | tcp port for v6 address | -| aztec | The aztec chain id | -| eth | The ethereum chain id | +| key | value | +| --------- | ----------------------- | +| id | "v4" | +| secp256k1 | The node's public key | +| ip | ipv4 address | +| tcp | tcp port | +| ip6 | ipv6 address | +| tcp6 | tcp port for v6 address | +| aztec | The aztec chain id | +| eth | The ethereum chain id | ### Transaction Gossip @@ -128,7 +126,7 @@ LibP2P supports the multiplexing of stream based transports such as TCP. There a #### Encryption handshake -Communication between nodes within LibP2P is encrypted. This is important to protect individual nodes and the network at large from malicious actors. Establishing keys requires a secure handshake protocol. Client's must specify LibP2P's [noise](https://docs.libp2p.io/concepts/secure-comm/noise/) protocol for this purpose. +Communication between nodes within LibP2P is encrypted. This is important to protect individual nodes and the network at large from malicious actors. Establishing keys requires a secure handshake protocol. Client's must specify LibP2P's [noise](https://docs.libp2p.io/concepts/secure-comm/noise/) protocol for this purpose. #### GossipSub @@ -161,17 +159,16 @@ Aztec will use LibP2P's GossipSub protocol for transaction propagation. Nodes mu The table below contains some of the relevant configuration properties and their default values. These parameters can be validated on testnet but it is expected that for the Aztec network, clients would use similar values, perhaps reducing peering degree slightly to favour reduced bandwidth over message propagation latency. +| Parameter | Description | Value | +| ------------------ | -------------------------------------------------------------------- | -------- | +| D | The desired peering degree | 6 | +| D_low | The peering degree low watermark | 4 | +| D_high | The peering degree high watermark | 12 | +| heartbeat_interval | The time between heartbeats\* | 1 second | +| mcache_len | The number of history windows before messages are ejected from cache | 5 | +| mcache_gossip | The number of history windows for messages to be gossiped | 3 | -| Parameter | Description | Value | -| -------- | -------- | -------- | -| D | The desired peering degree | 6 | -| D_low | The peering degree low watermark | 4 | -| D_high | The peering degree high watermark | 12 | -| heartbeat_interval | The time between heartbeats* | 1 second | -| mcache_len | The number of history windows before messages are ejected from cache | 5 | -| mcache_gossip | The number of history windows for messages to be gossiped | 3 | - -(*)Several things happen at the heartbeat interval: +(\*)Several things happen at the heartbeat interval: 1. The nature of peerings are evaluated and changed if necessary 2. Message IDs are gossiped to a randomly selected set of metadata only peers @@ -197,6 +194,6 @@ GossipSub does not include a mechanism for synchronising the global set of messa 1. Aztec transactions are large, approximately 40Kb. Downloading the entire pool would require transferring in the order of 100s of MB of data. At best this is undesirable and at worst it represents a DoS vector. -2. It is largely redundant. At the point at which a node joins the network, it is likely that production of a block is already underway and many of the transactions that would be downloaded will be removed as soon as that block is published. +2. It is largely redundant. At the point at which a node joins the network, it is likely that production of a block is already underway and many of the transactions that would be downloaded will be removed as soon as that block is published. -3. Clients will naturally synchronise the transaction pool by joining the gossiping network and waiting for 1 or 2 blocks. New transactions will be received into the client's local pool and old transactions unknown to the client will be removed as blocks are published. \ No newline at end of file +3. Clients will naturally synchronise the transaction pool by joining the gossiping network and waiting for 1 or 2 blocks. New transactions will be received into the client's local pool and old transactions unknown to the client will be removed as blocks are published. diff --git a/yellow-paper/docs/gas-and-fees/fee-payments-and-metering.md b/docs/docs/protocol-specs/gas-and-fees/fee-payments-and-metering.md similarity index 97% rename from yellow-paper/docs/gas-and-fees/fee-payments-and-metering.md rename to docs/docs/protocol-specs/gas-and-fees/fee-payments-and-metering.md index 22042f28de9a..b8a7c1db90e5 100644 --- a/yellow-paper/docs/gas-and-fees/fee-payments-and-metering.md +++ b/docs/docs/protocol-specs/gas-and-fees/fee-payments-and-metering.md @@ -55,7 +55,7 @@ Transactions will be divided into 3 phases: All of these phases occur **within the same transaction**, ultimately resulting in 2 sets of public inputs being emitted from the private kernel circuits. Those related to the fee payment and those related to the application logic. State changes requested by the application logic are reverted if any component fails. State changes in the fee preparation and distribution components are only reverted if either of those components fail. -![Transaction Components](../gas-and-fees/images/gas-and-fees/Transaction.png) +![Transaction Components](/img/protocol-specs/gas-and-fees/Transaction.png) The fee preparation and fee distribution phases respectively are responsible for ensuring that sufficient quantity of the fee payment asset is made available for the transaction and that it is correctly distributed to the sequencer with any refund being returned to the transaction sender. The sequencer will have have agency over which contract methods they are willing to accept for execution in these phases and will have visibility over the arguments passed to them. This is important as these functions must be successfully executed in order for the sequencer to be paid. It is assumed that the network will settle on a number of universally recognised fee payment contracts implementing fee preparation and distribution. @@ -90,12 +90,12 @@ An example of L2 gas amortization could be the transaction sender specifying a m TotalGasToBeAmortised = (1024 - 2) * GMerge + GRoot L2AmortizedGasLimit = TotalGasToBeAmortised / 1024 -Where +Where GMerge = The gas cost of proving the merge rollup circuit. GRoot = The gas cost of proving the root rollup circuit. ``` -In this example, were the transaction to be included within a rollup larger than 1024 transactions, the transaction sender would be refunded this amortization difference. +In this example, were the transaction to be included within a rollup larger than 1024 transactions, the transaction sender would be refunded this amortization difference. The private kernel circuits will output 8 `Gas` values. The 6 `GasLimit`'s represent maximum quantities of gas that the transaction sender permits to be consumed. Insufficient limits will cause the transaction to revert with an `OutOfGas` condition. Fees will be refunded to the transaction sender for unused quantities of gas, The `FeeDistributionGas` values are fixed amounts of gas effectively representing fixed fees that the transaction sender is willing to pay for their chosen fee distribution. @@ -129,7 +129,7 @@ L1Fee = (L1AmortizedGasLimit + L1TxGasLimit) * feePerL1Gas L2Fee = (L2AmortizedGasLimit + L2TxGasLimit + L2FeeDistributionGas) * feePerL2Gas DAFee = (DAAmortizedGasLimit + DATxGasLimit + DAFeeDistributionGas) * feePerDAGas -TotalFee = L1Fee + L2Fee + DAFee +TotalFee = L1Fee + L2Fee + DAFee ``` ## Executing Transactions and Collecting Fees @@ -150,12 +150,11 @@ The transaction's fee preparation and fee distribution functions must be called | `DAGasUsed` | The accumulated quantity of DA gas used, both amortized and per-transaction | | `feeRecipient` | The aztec address designated as the recipient of fees for the current block | - The values of gas used must be calculated and applied appropriately by the sequencer, a variety of constraints are in place for this. 1. The sequencer specifies the size of rollup being produced to the base rollup circuit and uses this value when calculating amortized gas consumption. This value is a public input of the base rollup circuit. 2. The sequencer specifies the fee recipient to the base rollup circuit and uses this value in fee distribution calls. This value is a public input of the base rollup circuit. -3. The sequencer calculates an initial set of values for consumed transaction specific and amortized gas. +3. The sequencer calculates an initial set of values for consumed transaction specific and amortized gas. 4. All forms of gas usage are accumulated by the public VM circuit and form part of the public inputs for the public kernel circuit. 5. The public kernel circuit public inputs also include the gas and fee related inputs provided to the public VM circuit. 6. The base rollup circuit computes the total amount of L1, L2 and DA gas consumed by the transaction, considering both private and public execution and transaction specific and amortized gas. It also considers reverted public execution. These values are public inputs to the circuit. @@ -198,7 +197,7 @@ sequenceDiagram Alice->>AccountContract: run entrypoint AccountContract->>FPA: enqueue FPA.pay_fee(max_fee) msg_sender == Alice as fee distribution function AccountContract->>App: app logic - App->>AccountContract: + App->>AccountContract: AccountContract->>Alice: finished private execution Alice->>Sequencer: tx object @@ -208,7 +207,7 @@ sequenceDiagram FPA->>Sequencer: Alice has >= funds required from tx object Sequencer->>App: app logic - App->>Sequencer: + App->>Sequencer: Sequencer->>FPA: FPA.pay_fee(max_fee) FPA->>FPA: calculate fee based on inputs to VM circuit @@ -238,13 +237,13 @@ sequenceDiagram Alice->>Alice: transient auth witness for AST private transfer Alice->>AccountContract: run entrypoint AccountContract->>FPC: private_fee_entrypoint(AST, max_fee, nonce) - + FPC->>AST: AST.transfer(FPC, max_fee + commission, nonce) AST->>AccountContract: check auth witness FPC->>FPC: enqueue FPA.private_fee_payment(max_fee) msg_sender == FPC as fee distribution function - FPC->>AccountContract: + FPC->>AccountContract: AccountContract->>App: app logic - App->>AccountContract: + App->>AccountContract: AccountContract->>Alice: finished private execution Alice->>Sequencer: tx object @@ -254,7 +253,7 @@ sequenceDiagram FPA->>Sequencer: FPC has >= funds required from tx object Sequencer->>App: app logic - App->>Sequencer: + App->>Sequencer: Sequencer->>FPA: FPA.private_fee_payment(max_fee) FPA->>FPA: calculate fee based on inputs to VM circuit @@ -288,10 +287,10 @@ sequenceDiagram activate FPC FPC->>FPC: enqueue FPC.public_fee_preparation(Alice, AST, max_fee, nonce) as fee preparation with msg_sender == FPC FPC->>FPC: enqueue FPC.public_fee_payment(Alice, AST, max_fee) as fee distribution with msg_sender == FPC - FPC->>AccountContract: + FPC->>AccountContract: deactivate FPC AccountContract->>App: app logic - App->>AccountContract: + App->>AccountContract: AccountContract->>Alice: finished private execution Alice->>Sequencer: tx object @@ -301,15 +300,15 @@ sequenceDiagram activate FPC FPC->>AST: AST.transfer_public(Alice, FPC, max_fee + commission, nonce) AST->>AccountContract: check auth witness - AccountContract->>AST: - AST->>FPC: + AccountContract->>AST: + AST->>FPC: FPC->>FPA: FPA.check_balance(max_fee) - FPA->>FPC: + FPA->>FPC: FPC->>Sequencer: FPC has the funds deactivate FPC Sequencer->>App: app logic - App->>Sequencer: + App->>Sequencer: Sequencer->>Sequencer: Recognise whitelisted function FPC.public_fee_payment(Alice, AST, max_fee) and msg.sender == FPC Sequencer->>FPC: FPC.public_fee_payment(Alice, AST, max_fee) @@ -319,7 +318,7 @@ sequenceDiagram FPA->>Sequencer: Sequencer's balance is increased by fee amount FPA->>FPC: rebate value FPC->>AST: AST.transfer_public(FPC, Alice, rebate, 0) - AST->>FPC: + AST->>FPC: FPC->>Alice: Alice's balance is increased by rebate value deactivate FPC ``` @@ -343,7 +342,7 @@ sequenceDiagram Alice->>DApp: run entrypoint DApp->>AccountContract: check auth witness - AccountContract->>DApp: + AccountContract->>DApp: DApp->>DApp: check if will sponsor action DApp->>FPA: enqueue FPA.pay_fee(max_fee) and msg_sender == DApp as fee distribution DApp->>DApp: app logic @@ -356,7 +355,7 @@ sequenceDiagram FPA->>Sequencer: DApp has >= funds required from tx object Sequencer->>DApp: app logic - DApp->>Sequencer: + DApp->>Sequencer: Sequencer->>FPA: FPA.pay_fee(max_fee) FPA->>FPA: calculate fee based on inputs to VM circuit diff --git a/yellow-paper/docs/gas-and-fees/fee-schedule.md b/docs/docs/protocol-specs/gas-and-fees/fee-schedule.md similarity index 100% rename from yellow-paper/docs/gas-and-fees/fee-schedule.md rename to docs/docs/protocol-specs/gas-and-fees/fee-schedule.md diff --git a/yellow-paper/docs/gas-and-fees/index.md b/docs/docs/protocol-specs/gas-and-fees/index.md similarity index 100% rename from yellow-paper/docs/gas-and-fees/index.md rename to docs/docs/protocol-specs/gas-and-fees/index.md diff --git a/yellow-paper/docs/intro.md b/docs/docs/protocol-specs/intro.md similarity index 100% rename from yellow-paper/docs/intro.md rename to docs/docs/protocol-specs/intro.md diff --git a/yellow-paper/docs/l1-smart-contracts/frontier.md b/docs/docs/protocol-specs/l1-smart-contracts/frontier.md similarity index 87% rename from yellow-paper/docs/l1-smart-contracts/frontier.md rename to docs/docs/protocol-specs/l1-smart-contracts/frontier.md index 682c4b0e0a25..885ae870e0ca 100644 --- a/yellow-paper/docs/l1-smart-contracts/frontier.md +++ b/docs/docs/protocol-specs/l1-smart-contracts/frontier.md @@ -5,21 +5,21 @@ title: Frontier Merkle Tree The Frontier Merkle Tree is an append only Merkle tree that is optimized for minimal storage on chain. By storing only the right-most non-empty node at each level of the tree we can always extend the tree with a new leaf or compute the root without needing to store the entire tree. We call these values the frontier of the tree. -If we have the next index to insert at and the current frontier, we have everything needed to extend the tree or compute the root, with much less storage than a full merkle tree. +If we have the next index to insert at and the current frontier, we have everything needed to extend the tree or compute the root, with much less storage than a full merkle tree. Note that we're not actually keeping track of the data in the tree: we only store what's minimally required in order to be able to compute the root after inserting a new element. We will go through a few diagrams and explanations to understand how this works. And then a pseudo implementation is provided. - ## Insertion + Whenever we are inserting, we need to update the "root" of the largest subtree possible. This is done by updating the node at the level of the tree, where we have just inserted its right-most descendant. -This can sound a bit confusing, so we will go through a few examples. +This can sound a bit confusing, so we will go through a few examples. At first, say that we have the following tree, and that it is currently entirely empty. -![alt text](images/frontier/image-1.png) +![alt text](/img/protocol-specs/l1-smart-contracts/frontier/image-1.png) ### The first leaf @@ -27,7 +27,7 @@ When we are inserting the first leaf (lets call it A), the largest subtree is th In this case, we simply need to store the leaf value in `frontier[0]` and then we are done. For the sake of visualization, we will be drawing the elements in the `frontier` in blue. -![alt text](images/frontier/image-2.png) +![alt text](/img/protocol-specs/l1-smart-contracts/frontier/image-2.png) Notice that this will be the case whenever we are inserting a leaf at an even index. @@ -40,13 +40,14 @@ Therefore, we will compute the root of this subtree, `H(frontier[0],B)` and stor Notice, that we don't need to store the leaf B itself, since we won't be needing it for any future computations. This is what makes the frontier tree efficient - we get away with storing very little data. -![alt text](images/frontier/image-3.png) +![alt text](/img/protocol-specs/l1-smart-contracts/frontier/image-3.png) ### Third leaf + When inserting the third leaf, we are again back to the largest subtree being filled by the insertion being itself at level 0. The update will look similar to the first, where we only update `frontier[0]` with the new leaf. -![alt text](images/frontier/image-4.png) +![alt text](/img/protocol-specs/l1-smart-contracts/frontier/image-4.png) ### Fourth leaf @@ -56,39 +57,39 @@ Now the largest subtree getting filled by the insertion is at level 2. To compute the new subtree root, we have to compute `F = H(frontier[0], E)` and then `G = H(frontier[1], F)`. G is then stored in `frontier[2]`. - -As before, notice that we are only updating one value in the frontier. -![alt text](images/frontier/image-5.png) +As before, notice that we are only updating one value in the frontier. +![alt text](/img/protocol-specs/l1-smart-contracts/frontier/image-5.png) ## Figuring out what to update To figure out which level to update in the frontier, we simply need to figure out what the height is of the largest subtree that is filled by the insertion. -While this might sound complex, it is actually quite simple. +While this might sound complex, it is actually quite simple. Consider the following extension of the diagram. We have added the level to update, along with the index of the leaf in binary. Seeing any pattern? -![alt text](images/frontier/image-6.png) +![alt text](/img/protocol-specs/l1-smart-contracts/frontier/image-6.png) The level to update is simply the number of trailing ones in the binary representation of the index. -For a binary tree, we have that every `1` in the binary index represents a "right turn" down the tree. +For a binary tree, we have that every `1` in the binary index represents a "right turn" down the tree. Walking up the tree from the leaf, we can simply count the number of right turns until we hit a left-turn. ## How to compute the root -Computing the root based on the frontier is also quite simple. +Computing the root based on the frontier is also quite simple. We can use the last index inserted a leaf at to figure out how high up the frontier we should start. -Then we know that anything that is at the right of the frontier has not yet been inserted, so all of these values are simply "zeros" values. +Then we know that anything that is at the right of the frontier has not yet been inserted, so all of these values are simply "zeros" values. Zeros here are understood as the root for a subtree only containing zeros. For example, if we take the tree from above and compute the root for it, we would see that level 2 was updated last. Meaning that we can simply compute the root as `H(frontier[2], zeros[2])`. -![alt text](images/frontier/image-7.png) +![alt text](/img/protocol-specs/l1-smart-contracts/frontier/image-7.png) For cases where we have built further, we simply "walk" up the tree and use either the frontier value or the zero value for the level. ## Pseudo implementation + ```python class FrontierTree: HEIGHT: immutable(uint256) @@ -107,7 +108,7 @@ class FrontierTree: def compute_level(_index: uint256) -> uint256: ''' - We can get the right of the most filled subtree by + We can get the right of the most filled subtree by counting the number of trailing ones in the index ''' count = 0 @@ -154,6 +155,5 @@ class FrontierTree: ``` ## Optimizations -- The `zeros` can be pre-computed and stored in the `Inbox` directly, this way they can be shared across all of the trees. - +- The `zeros` can be pre-computed and stored in the `Inbox` directly, this way they can be shared across all of the trees. diff --git a/yellow-paper/docs/l1-smart-contracts/index.md b/docs/docs/protocol-specs/l1-smart-contracts/index.md similarity index 92% rename from yellow-paper/docs/l1-smart-contracts/index.md rename to docs/docs/protocol-specs/l1-smart-contracts/index.md index ad676a95d752..0a2f7a924d8d 100644 --- a/yellow-paper/docs/l1-smart-contracts/index.md +++ b/docs/docs/protocol-specs/l1-smart-contracts/index.md @@ -4,7 +4,7 @@ title: Cross-chain communication This section describes what our L1 contracts do, what they are responsible for and how they interact with the circuits. -Note that the only reason that we even have any contracts is to facilitate cross-chain communication. +Note that the only reason that we even have any contracts is to facilitate cross-chain communication. The contracts are not required for the rollup to function, but required to bridge assets and to reduce the cost of light nodes. :::info Purpose of contracts @@ -12,11 +12,11 @@ The purpose of the L1 contracts are simple: - Facilitate cross-chain communication such that L1 liquidity can be used on L2 - Act as a validating light node for L2 that every L1 node implicitly run -::: + ::: ## Overview -When presented with a new [`ProvenBlock`](../rollup-circuits/root-rollup.md) and its proof, an Aztec node can be convinced of its validity if the proof passes and the `Header.last_archive` matches the `archive` of the node (archive here represents a root of [archive tree](../state/archive.md)). +When presented with a new [`ProvenBlock`](../rollup-circuits/root-rollup.md) and its proof, an Aztec node can be convinced of its validity if the proof passes and the `Header.last_archive` matches the `archive` of the node (archive here represents a root of [archive tree](../state/archive.md)). The `archive` used as public input is the archive after the new header is inserted (see [root rollup](./../rollup-circuits/root-rollup.md)). ```python @@ -31,8 +31,8 @@ def process(block: ProvenBlock, proof: Proof): assert proof.verify(header, block.archive) assert self.inbox.consume() == header.in_hash assert self.outbox.insert( - block_number, - header.content_commitment.out_hash, + block_number, + header.content_commitment.out_hash, header.content_commitment.tx_tree_height + math.ceil(log2(MAX_NEW_L2_TO_L1_MSGS_PER_TX)) ) self.archive = block.archive @@ -44,15 +44,15 @@ def process(block: ProvenBlock, proof: Proof): The argument to the `insert` function is the `outbox` is the heigh of the message tree. Since every transaction can hold more than 1 message, it might add multiple layers to the tree. For a binary tree, the number of extra layers to add is computed as `math.ceil(log2(MAX_NEW_L2_TO_L1_MSGS_PER_TX))`. -Currently, `MAX_NEW_L2_TO_L1_MSGS_PER_TX = 2` which means that we are simply adding 1 extra layer. +Currently, `MAX_NEW_L2_TO_L1_MSGS_PER_TX = 2` which means that we are simply adding 1 extra layer. ::: -While the `ProvenBlock` must be published and available for nodes to build the state of the rollup, we can build the validating light node (the contract) such that as long as the node can be _convinced_ that the data is available we can progress the state. +While the `ProvenBlock` must be published and available for nodes to build the state of the rollup, we can build the validating light node (the contract) such that as long as the node can be _convinced_ that the data is available we can progress the state. This means our light node can be built to only require a subset of the `ProvenBlock` to be published to Ethereum L1 as calldata and use a different data availability layer for most of the block body. Namely, we need the cross-chain messages to be published to L1, but the rest of the block body can be published to a different data availability layer. :::info Validium or Rollup -If a different data availability layer than Ethereum is used for the block body, we are effectively building a Validium. +If a different data availability layer than Ethereum is used for the block body, we are effectively building a Validium. If we use Ethereum for the block body, we are building a Rollup. ::: @@ -91,8 +91,8 @@ StateTransitioner --> Verifier: verify() ### State transitioner -The state transitioner is the heart of the validating light node for the L2. -The contract keeps track of the current state of the L2 and progresses this state when a valid L2 block is received. +The state transitioner is the heart of the validating light node for the L2. +The contract keeps track of the current state of the L2 and progresses this state when a valid L2 block is received. It also facilitates cross-chain communication (communication between the L1 inbox and outbox contracts). ```python @@ -124,8 +124,8 @@ class StateTransitioner: assert VERIFIER.verify(header, archive, proof) assert self.INBOX.consume() == header.content_commitment.in_hash assert self.OUTBOX.insert( - block_number, - header.content_commitment.out_hash, + block_number, + header.content_commitment.out_hash, header.content_commitment.tx_tree_height + math.ceil(log2(MAX_NEW_L2_TO_L1_MSGS_PER_TX)) ) self.archive = archive @@ -148,7 +148,7 @@ class StateTransitioner: The state transitioner should be connected to an oracle which addresses the availability condition. -For the case of a rollup, this "oracle" will be deriving the `TxsHash` from calldata and blobs. +For the case of a rollup, this "oracle" will be deriving the `TxsHash` from calldata and blobs. For a validium it should be connected to a bridge that it can use to verify that the data is available on the other chain. For a generic DA that publishes data commitments to Ethereum, the oracle could be a snark proof that opens the data commitment from the bridge and computes the `TxsHash` from it. @@ -157,7 +157,7 @@ By having the availability oracle be independent from state progression we can e For more information around the requirements we have for the availability oracle, see [Data Availability](../data-publication-and-availability/index.md). -An interesting observation around the availability oracle is that the `OutHash` and `InHash` don't need to be explicitly proven available through it. +An interesting observation around the availability oracle is that the `OutHash` and `InHash` don't need to be explicitly proven available through it. The `InHash` is already proven as part of the L1 inbox, as we will see in a second. And the `OutHash` consists entirely of a subset of the contents of the `TxsHash`, which is already proven available. @@ -165,30 +165,30 @@ And the `OutHash` consists entirely of a subset of the contents of the `TxsHash` ### Registry -To keep one location where all the core rollup contracts can be found, we have a registry contract. -The registry is a contract that holds the current and historical addresses of the core rollup contracts. -The addresses of a rollup deployment are contained in a snapshot, and the registry is tracking version-snapshot pairs. -Depending on the upgrade scheme, it might be used to handle upgrades, or it could entirely be removed. -It is generally the one address that a node MUST know about, as it can then tell the node where to find the remainder of the contracts. +To keep one location where all the core rollup contracts can be found, we have a registry contract. +The registry is a contract that holds the current and historical addresses of the core rollup contracts. +The addresses of a rollup deployment are contained in a snapshot, and the registry is tracking version-snapshot pairs. +Depending on the upgrade scheme, it might be used to handle upgrades, or it could entirely be removed. +It is generally the one address that a node MUST know about, as it can then tell the node where to find the remainder of the contracts. This is for example used when looking for the address new L2 blocks should be published to. ## Message Bridges To let users communicate between L1 and the L2, we are using message bridges, namely an L1 inbox that is paired to an L2 outbox, and an L2 inbox that is paired to an L1 outbox. -![Alt text](images/com-abs-6.png) +![Alt text](/img/protocol-specs/l1-smart-contracts/com-abs-6.png) :::info Naming is based from the PoV of the state transitioner. ::: -While we logically have 4 boxes, we practically only require 3 of those. -The L2 inbox is not real - but only logical. -This is due to the fact that they are always inserted and then consumed in the same block! +While we logically have 4 boxes, we practically only require 3 of those. +The L2 inbox is not real - but only logical. +This is due to the fact that they are always inserted and then consumed in the same block! Insertions require a L2 transaction, and it is then to be consumed and moved to the L1 outbox by the state transitioner in the same block. ### Portals -When deploying a contract on L2, it is possible to specify its "portal" address. +When deploying a contract on L2, it is possible to specify its "portal" address. This is an immutable variable, that can be used to constrain who the L2 contract expects messages from, and who it sends messages to. ### Messages @@ -220,32 +220,32 @@ struct L2ToL1Msg { } ``` -Beware, that while we speak of messages, we are practically passing around only their **hashes** to reduce cost. -The `version` value of the `L2Actor` is the version of the rollup, which is intended to be used to specify which version of the rollup the message is intended for or sent from. +Beware, that while we speak of messages, we are practically passing around only their **hashes** to reduce cost. +The `version` value of the `L2Actor` is the version of the rollup, which is intended to be used to specify which version of the rollup the message is intended for or sent from. This way, multiple rollup instances can use the same inbox/outbox contracts. :::info Why a single hash? -Compute on L1 is expensive, but storage is extremely expensive! -To reduce overhead, we trade storage for computation and only commit to the messages and then "open" these for consumption later. -However, since computation also bears significant we need to use a hash function that is relatively cheap on L1, while still being doable inside a snark. +Compute on L1 is expensive, but storage is extremely expensive! +To reduce overhead, we trade storage for computation and only commit to the messages and then "open" these for consumption later. +However, since computation also bears significant we need to use a hash function that is relatively cheap on L1, while still being doable inside a snark. For this purpose a modded SHA256 was chosen, modded here meaning that it fits the output value into a single field element using the modulo operator. ::: Some additional discussion/comments on the message structure can be found in [The Republic](https://forum.aztec.network/t/the-republic-a-flexible-optional-governance-proposal-with-self-governed-portals/609/2#supporting-pending-messages-5). -Since any data that is moving from one chain to the other at some point will live on L1, it will be PUBLIC. +Since any data that is moving from one chain to the other at some point will live on L1, it will be PUBLIC. While this is fine for L1 consumption (which is public in itself), we want to ensure that the L2 consumption can be private. -To support this, we use a nullifier scheme similar to what we are doing for the other [notes](./../state/note-hash-tree.md). +To support this, we use a nullifier scheme similar to what we are doing for the other [notes](./../state/note-hash-tree.md). As part of the nullifier computation we then use the `secret` which hashes to the `secretHash`, this ensures that only actors with knowledge of `secret` will be able to see when it is spent on L2. -Any message that is consumed on one side MUST be moved to the other side. -This is to ensure that the messages exist AND are only consumed once. +Any message that is consumed on one side MUST be moved to the other side. +This is to ensure that the messages exist AND are only consumed once. The L1 contracts can handle one side, but the circuits must handle the other. :::info Is `secretHash` required? We are using the `secretHash` to ensure that the user can spend the message privately with a generic nullifier computation. -However, as the nullifier computation is almost entirely controlled by the app circuit (except the siloing, see [Nullifier Tree](./../state/nullifier-tree.md) ) applications could be made to simply use a different nullifier computation and have it become part of the content. -However, this reduces the developer burden and is quite easy to mess up. +However, as the nullifier computation is almost entirely controlled by the app circuit (except the siloing, see [Nullifier Tree](./../state/nullifier-tree.md) ) applications could be made to simply use a different nullifier computation and have it become part of the content. +However, this reduces the developer burden and is quite easy to mess up. For those reasons we have decided to use the `secretHash` as part of the message. ::: @@ -256,21 +256,20 @@ For those reasons we have decided to use the `secretHash` as part of the message When we say inbox, we are generally referring to the L1 contract that handles the L1 to L2 messages. The inbox takes messages from L1 contracts and inserts them into a series of message trees. -We build multiple "trees" instead of a single tree, since we are building one tree for every block and not one large with all the messages. +We build multiple "trees" instead of a single tree, since we are building one tree for every block and not one large with all the messages. The reasoning is fairly straight-forward; we need to split it into epochs such that a sequencer can build a proof based on a tree that is not going to update in the middle of the proof building. Such updates would allow DOS attacks on the sequencer, which is undesirable. To support this, we can simply introduce a "lag" between when trees are built and when they must be included. We can actually do this quite easily. -Say that whenever a new block is published, we start building a new tree. +Say that whenever a new block is published, we start building a new tree. Essentially meaning that at block $n$ we include tree $n$ which was created earlier (during block $n-1$). - Example visualized below. Here we have that tree $n$ is "fixed" when block $n$ needs to be published. And that tree $n+1$ is being built upon until block $n$ is being published. -![Feeding trees into the blocks](images/tree-order.png) +![Feeding trees into the blocks](/img/protocol-specs/l1-smart-contracts/tree-order.png) When the state transitioner is consuming a tree, it MUST insert the subtree into the "L2 outbox" ([message tree](./../state/index.md)). @@ -279,27 +278,27 @@ When a message is inserted into the inbox, the inbox **MUST** fill in the `sende - `L1Actor.actor`: The sender of the message (the caller), `msg.sender` - `L1Actor.chainId`: The chainId of the L1 chain sending the message, `block.chainId` -We MUST populate these values in the inbox, since we cannot rely on the user providing anything meaningful. -From the `L1ToL2Msg` we compute a hash of the message. +We MUST populate these values in the inbox, since we cannot rely on the user providing anything meaningful. +From the `L1ToL2Msg` we compute a hash of the message. This hash is what is moved by the state transitioner to the L2 outbox. -Since message from L1 to L2 can be inserted independently of the L2 block, the message transfer (moving from inbox into outbox) is not synchronous as it is for L2 to L1 messages. -This means that the message can be inserted into the inbox, but not yet moved to the outbox. -The message will then be moved to the outbox when the state transitioner is consuming the message as part of a block. +Since message from L1 to L2 can be inserted independently of the L2 block, the message transfer (moving from inbox into outbox) is not synchronous as it is for L2 to L1 messages. +This means that the message can be inserted into the inbox, but not yet moved to the outbox. +The message will then be moved to the outbox when the state transitioner is consuming the message as part of a block. Since the sequencers are required to move the entire subtree at once, you can be sure that the message will be moved to the outbox at some point. As mentioned earlier, this is done to ensure that the messages are not used to DOS the state transitioner. -Since we will be building the tree on L1, we need to use a gas-friendly hash-function such as SHA256. -However, as we need to allow users to prove inclusion in this tree, we cannot just insert the SHA256 tree into the rollup state, it requires too many constraints to be used by most small users. +Since we will be building the tree on L1, we need to use a gas-friendly hash-function such as SHA256. +However, as we need to allow users to prove inclusion in this tree, we cannot just insert the SHA256 tree into the rollup state, it requires too many constraints to be used by most small users. Therefore, we need to "convert" the tree into a tree using a more snark-friendly hash. This part is done in the [tree parity circuits](./../rollup-circuits/tree-parity.md). -Furthermore, to build the tree on L1, we need to put some storage on L1 such that the insertions don't need to provide a lot of merkle-related data which could be cumbersome to do and prone to race-conditions. -For example two insertions based on inclusion paths that are created at the same time will invalidate each other. -As storage costs an arm and a leg on L1, we need to be careful with how we store this. +Furthermore, to build the tree on L1, we need to put some storage on L1 such that the insertions don't need to provide a lot of merkle-related data which could be cumbersome to do and prone to race-conditions. +For example two insertions based on inclusion paths that are created at the same time will invalidate each other. +As storage costs an arm and a leg on L1, we need to be careful with how we store this. -Luckily for us, we can use a "frontier" merkle tree to store the messages. +Luckily for us, we can use a "frontier" merkle tree to store the messages. This is a special kind of append-only merkle tree that allows us to store very few elements in storage, but just enough for us to be able to extend it, and compute the root of the tree. Consult [Frontier Merkle Tree](#frontier-merkle-tree]) for more information on this. @@ -307,7 +306,6 @@ Assuming that we have these trees, we can build an `inbox` utilizing them as fol When a new block is published, we start building a new tree. Notice however, that if we have entirely filled the current tree, we can start building a new one immediately, and the blocks can then "catch up". - ```python class Inbox: STATE_TRANSITIONER: immutable(address) @@ -328,7 +326,7 @@ class Inbox: self.STATE_TRANSITIONER = _state_transitioner self.trees[1] = FrontierTree(self.HEIGHT) - + def insert(self, message: L1ToL2Message) -> bytes32: ''' Insert into the next FrontierTree. If the tree is full, creates a new one @@ -366,7 +364,7 @@ class Inbox: #### L2 Inbox -While the L2 inbox is not a real contract, it is a logical contract that apply mutations to the data similar to the L1 inbox to ensure that the sender cannot fake his position. +While the L2 inbox is not a real contract, it is a logical contract that apply mutations to the data similar to the L1 inbox to ensure that the sender cannot fake his position. This logic is handled by the kernel and rollup circuits. Just like the L1 variant, we must populate the `sender`: @@ -378,7 +376,7 @@ In practice, this is done in the kernel circuit of the L2, and the message hashe ### Outbox -The outboxes are the location where a user can consume messages from. +The outboxes are the location where a user can consume messages from. An outbox can only contain elements that have previously been removed from the paired inbox. diff --git a/yellow-paper/docs/state/note-hash-tree.md b/docs/docs/protocol-specs/state/note-hash-tree.md similarity index 100% rename from yellow-paper/docs/state/note-hash-tree.md rename to docs/docs/protocol-specs/state/note-hash-tree.md diff --git a/yellow-paper/docs/state/nullifier-tree.md b/docs/docs/protocol-specs/state/nullifier-tree.md similarity index 98% rename from yellow-paper/docs/state/nullifier-tree.md rename to docs/docs/protocol-specs/state/nullifier-tree.md index 036b69cff013..e33c294643d0 100644 --- a/yellow-paper/docs/state/nullifier-tree.md +++ b/docs/docs/protocol-specs/state/nullifier-tree.md @@ -40,7 +40,7 @@ Missing info: - Details of the hash to use, and a domain separator for the hash. We might not know the final hash that we'll use, but we should propose one, and we should probably also give each hash a name. - E.g. `compute_parent_node("nullifier parent node".to_field(), left_child, right_child)` where `compute_siloed_nullifier = pedersen_hash` (for now). -Pseudocode/algorithms for insertion, batch insertion, membership proofs, non-membership proofs, so that the security of our approach can be validated. We should discuss the best way to consistently present such information, for all sections of the yellow paper. +Pseudocode/algorithms for insertion, batch insertion, membership proofs, non-membership proofs, so that the security of our approach can be validated. We should discuss the best way to consistently present such information, for all sections of the protocol specs. EDIT: maybe all these comments should actually go in cryptography/merkle-tree.md --> diff --git a/yellow-paper/docs/state/public-data-tree.md b/docs/docs/protocol-specs/state/public-data-tree.md similarity index 96% rename from yellow-paper/docs/state/public-data-tree.md rename to docs/docs/protocol-specs/state/public-data-tree.md index 1c48c23a4d57..9489cfc40aa2 100644 --- a/yellow-paper/docs/state/public-data-tree.md +++ b/docs/docs/protocol-specs/state/public-data-tree.md @@ -39,5 +39,5 @@ Missing info: - Details of the hash to use, and a domain separator for the hash. We might not know the final hash that we'll use, but we should propose one, and we should probably also give each hash a name. - E.g. `compute_parent_node("nullifier parent node".to_field(), left_child, right_child)` where `compute_siloed_nullifier = pedersen_hash` (for now. Poseidon eventually, iiuc. Perhaps we should write this spec to state Poseidon). -Pseudocode/algorithms for insertion, batch insertion, membership proofs, non-membership proofs, so that the security of our approach can be validated. We should discuss the best way to consistently present such information, for all sections of the yellow paper. (EDIT: put this in cryptography/merkle-trees) +Pseudocode/algorithms for insertion, batch insertion, membership proofs, non-membership proofs, so that the security of our approach can be validated. We should discuss the best way to consistently present such information, for all sections of the protocol specs. (EDIT: put this in cryptography/merkle-trees) --> diff --git a/yellow-paper/docs/state/tree-implementations.md b/docs/docs/protocol-specs/state/tree-implementations.md similarity index 100% rename from yellow-paper/docs/state/tree-implementations.md rename to docs/docs/protocol-specs/state/tree-implementations.md diff --git a/yellow-paper/docs/todo.md b/docs/docs/protocol-specs/todo.md similarity index 100% rename from yellow-paper/docs/todo.md rename to docs/docs/protocol-specs/todo.md diff --git a/yellow-paper/docs/transactions/index.md b/docs/docs/protocol-specs/transactions/index.md similarity index 100% rename from yellow-paper/docs/transactions/index.md rename to docs/docs/protocol-specs/transactions/index.md diff --git a/yellow-paper/docs/transactions/local-execution.md b/docs/docs/protocol-specs/transactions/local-execution.md similarity index 97% rename from yellow-paper/docs/transactions/local-execution.md rename to docs/docs/protocol-specs/transactions/local-execution.md index adce86b68b67..f9f7e5c57c70 100644 --- a/yellow-paper/docs/transactions/local-execution.md +++ b/docs/docs/protocol-specs/transactions/local-execution.md @@ -5,8 +5,8 @@ Transactions are initiated via a _transaction execution request_ sent from the u - `origin` diff --git a/yellow-paper/docs/transactions/validity.md b/docs/docs/protocol-specs/transactions/validity.md similarity index 100% rename from yellow-paper/docs/transactions/validity.md rename to docs/docs/protocol-specs/transactions/validity.md diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index d2ffd760db23..b0a158adaf43 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -7,6 +7,7 @@ const math = require("remark-math"); const katex = require("rehype-katex"); const path = require("path"); const fs = require("fs"); +const macros = require("./src/katex-macros.js"); /** @type {import('@docusaurus/types').Config} */ const config = { @@ -52,7 +53,16 @@ const config = { }, routeBasePath: "/", remarkPlugins: [math], - rehypePlugins: [katex], + rehypePlugins: [ + [ + katex, + { + throwOnError: true, + globalGroup: true, + macros, + }, + ], + ], }, blog: false, theme: { @@ -199,6 +209,12 @@ const config = { position: "left", label: "Aztec Protocol", }, + { + type: "docSidebar", + sidebarId: "protocolSpecSidebar", + position: "left", + label: "Protocol Specification", + }, ], }, footer: { diff --git a/docs/package.json b/docs/package.json index 67a53d63e891..10f82ae2712c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -31,6 +31,7 @@ "prism-react-renderer": "^1.3.1", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-markdown": "6.0.0", "react-player": "^2.12.0", "rehype-katex": "5", "remark-math": "3" diff --git a/docs/sidebars.js b/docs/sidebars.js index 554a40b9663b..3759b8f16c69 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -51,7 +51,6 @@ const aztecNRSidebar = buildSidebarItemsFromStructure( "developers/contracts/references/aztec-nr" ); -console.log(aztecNRSidebar); /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ const sidebars = { docsSidebar: [ @@ -643,6 +642,232 @@ const sidebars = { "misc/aztec_connect_sunset", ], + + protocolSpecSidebar: [ + "protocol-specs/intro", + { + label: "Cryptography", + type: "category", + link: { type: "doc", id: "protocol-specs/cryptography/index" }, + items: [ + { + label: "Proving System", + type: "category", + link: { + type: "doc", + id: "protocol-specs/cryptography/proving-system/performance-targets", + }, + items: [ + "protocol-specs/cryptography/proving-system/performance-targets", + "protocol-specs/cryptography/proving-system/overview", + "protocol-specs/cryptography/proving-system/data-bus", + ], + }, + { + label: "Hashing", + type: "category", + link: { + type: "doc", + id: "protocol-specs/cryptography/hashing/hashing", + }, + items: [ + "protocol-specs/cryptography/hashing/hashing", + "protocol-specs/cryptography/hashing/poseidon2", + "protocol-specs/cryptography/hashing/pedersen", + ], + }, + "protocol-specs/cryptography/merkle-trees", + ], + }, + { + label: "Addresses & Keys", + type: "category", + link: { type: "doc", id: "protocol-specs/addresses-and-keys/index" }, + items: [ + "protocol-specs/addresses-and-keys/address", + "protocol-specs/addresses-and-keys/keys-requirements", + "protocol-specs/addresses-and-keys/keys", + { + label: "Example Usage of Keys", + type: "category", + items: [ + "protocol-specs/addresses-and-keys/example-usage/nullifier", + "protocol-specs/addresses-and-keys/example-usage/diversified-and-stealth-keys", + "protocol-specs/addresses-and-keys/example-usage/tag-sequence-derivation", + "protocol-specs/addresses-and-keys/example-usage/encrypt-and-tag", + ], + }, + "protocol-specs/addresses-and-keys/precompiles", + "protocol-specs/addresses-and-keys/diversified-and-stealth", + ], + }, + { + label: "State", + type: "category", + link: { type: "doc", id: "protocol-specs/state/index" }, + items: [ + "protocol-specs/state/tree-implementations", + "protocol-specs/state/archive", + "protocol-specs/state/note-hash-tree", + "protocol-specs/state/nullifier-tree", + "protocol-specs/state/public-data-tree", + ], + }, + { + label: "Transactions", + type: "category", + link: { type: "doc", id: "protocol-specs/transactions/index" }, + items: [ + "protocol-specs/transactions/local-execution", + "protocol-specs/transactions/public-execution", + "protocol-specs/transactions/tx-object", + "protocol-specs/transactions/validity", + ], + }, + { + label: "Bytecode", + type: "category", + link: { type: "doc", id: "protocol-specs/bytecode/index" }, + items: [], + }, + { + label: "Contract Deployment", + type: "category", + link: { type: "doc", id: "protocol-specs/contract-deployment/index" }, + items: [ + "protocol-specs/contract-deployment/classes", + "protocol-specs/contract-deployment/instances", + ], + }, + { + label: "Calls", + type: "category", + link: { type: "doc", id: "protocol-specs/calls/index" }, + items: [ + "protocol-specs/calls/sync-calls", + "protocol-specs/calls/enqueued-calls", + "protocol-specs/calls/batched-calls", + "protocol-specs/calls/static-calls", + "protocol-specs/calls/delegate-calls", + "protocol-specs/calls/unconstrained-calls", + "protocol-specs/calls/public-private-messaging", + ], + }, + { + label: "L1 smart contracts", + type: "category", + link: { type: "doc", id: "protocol-specs/l1-smart-contracts/index" }, + items: ["protocol-specs/l1-smart-contracts/frontier"], + }, + { + label: "Data availability", + type: "category", + link: { + type: "doc", + id: "protocol-specs/data-publication-and-availability/index", + }, + items: [ + "protocol-specs/data-publication-and-availability/overview", + "protocol-specs/data-publication-and-availability/published-data", + ], + }, + { + label: "Logs", + type: "category", + link: { type: "doc", id: "protocol-specs/logs/index" }, + items: [], + }, + { + label: "Pre-compiled Contracts", + type: "category", + link: { type: "doc", id: "protocol-specs/pre-compiled-contracts/index" }, + items: ["protocol-specs/pre-compiled-contracts/registry"], + }, + { + label: "Private Message Delivery", + type: "category", + link: { + type: "doc", + id: "protocol-specs/private-message-delivery/index", + }, + items: [ + "protocol-specs/private-message-delivery/private-msg-delivery", // renamed to avoid routing problems + "protocol-specs/private-message-delivery/send-note-guidelines", + ], + }, + { + label: "Gas & Fees", + type: "category", + link: { type: "doc", id: "protocol-specs/gas-and-fees/index" }, + items: [ + "protocol-specs/gas-and-fees/fee-payments-and-metering", + "protocol-specs/gas-and-fees/fee-schedule", + ], + }, + { + label: "Decentralization", + type: "category", + link: { type: "doc", id: "protocol-specs/decentralization/governance" }, + items: [ + "protocol-specs/decentralization/actors", + "protocol-specs/decentralization/governance", + "protocol-specs/decentralization/block-production", + "protocol-specs/decentralization/p2p-network", + ], + }, + { + label: "Circuits", + type: "category", + link: { type: "doc", id: "protocol-specs/circuits/high-level-topology" }, + items: [ + "protocol-specs/circuits/private-function", + "protocol-specs/circuits/private-kernel-initial", + "protocol-specs/circuits/private-kernel-inner", + "protocol-specs/circuits/private-kernel-reset", + "protocol-specs/circuits/private-kernel-tail", + "protocol-specs/circuits/public-kernel-initial", + "protocol-specs/circuits/public-kernel-inner", + "protocol-specs/circuits/public-kernel-tail", + ], + }, + { + label: "Rollup Circuits", + type: "category", + link: { type: "doc", id: "protocol-specs/rollup-circuits/index" }, + items: [ + "protocol-specs/rollup-circuits/base-rollup", + "protocol-specs/rollup-circuits/merge-rollup", + "protocol-specs/rollup-circuits/tree-parity", + "protocol-specs/rollup-circuits/root-rollup", + ], + }, + { + label: "Aztec (Public) VM", + type: "category", + link: { type: "doc", id: "protocol-specs/public-vm/index" }, + items: [ + "protocol-specs/public-vm/intro", + "protocol-specs/public-vm/state", + "protocol-specs/public-vm/memory-model", + "protocol-specs/public-vm/context", + "protocol-specs/public-vm/execution", + "protocol-specs/public-vm/nested-calls", + "protocol-specs/public-vm/instruction-set", + { + label: "AVM Circuit", + type: "category", + link: { type: "doc", id: "protocol-specs/public-vm/circuit-index" }, + items: [ + "protocol-specs/public-vm/avm-circuit", + "protocol-specs/public-vm/control-flow", + "protocol-specs/public-vm/alu", + "protocol-specs/public-vm/bytecode-validation-circuit", + ], + }, + "protocol-specs/public-vm/type-structs", + ], + }, + ], }; module.exports = sidebars; diff --git a/docs/src/katex-macros.js b/docs/src/katex-macros.js new file mode 100644 index 000000000000..f60a6f0b66b9 --- /dev/null +++ b/docs/src/katex-macros.js @@ -0,0 +1,80 @@ +module.exports = { + "\\sk": "\\color{red}{sk}\\color{black}{}", + "\\seed": "\\color{red}\\text{{seed}}\\color{black}{}", + "\\nskm": "\\color{red}{nsk_m}\\color{black}{}", + "\\tskm": "\\color{red}{tsk_m}\\color{black}{}", + "\\ivskm": "\\color{red}{ivsk_m}\\color{black}{}", + "\\ovskm": "\\color{red}{ovsk_m}\\color{black}{}", + + "\\Npkm": "\\color{green}{Npk_m}\\color{black}{}", + "\\Tpkm": "\\color{green}{Tpk_m}\\color{black}{}", + "\\Ivpkm": "\\color{green}{Ivpk_m}\\color{black}{}", + "\\Ovpkm": "\\color{green}{Ovpk_m}\\color{black}{}", + + "\\address": "\\color{green}{address}\\color{black}{}", + "\\codehash": "\\color{green}{code_hash}\\color{black}{}", + "\\constructorhash": "\\color{green}{constructor_hash}\\color{black}{}", + "\\classid": "\\color{green}{classid}\\color{black}{}", + + "\\nskapp": "\\color{red}{nsk_{app}}\\color{black}{}", + "\\tskapp": "\\color{red}{tsk_{app}}\\color{black}{}", + "\\ivskapp": "\\color{red}{ivsk_{app}}\\color{black}{}", + "\\ovskapp": "\\color{red}{ovsk_{app}}\\color{black}{}", + + "\\Nkapp": "\\color{orange}{Nk_{app}}\\color{black}{}", + + "\\Npkapp": "\\color{green}{Npk_{app}}\\color{black}{}", + + "\\Ivpkapp": "\\color{green}{Ivpk_{app}}\\color{black}{}", + + "\\happL": "\\color{green}{h_{app}^L}\\color{black}{}", + "\\happn": "\\color{green}{h_{app}^n}\\color{black}{}", + "\\happiv": "\\color{green}{h_{app}^{iv}}\\color{black}{}", + + "\\d": "\\color{green}{d}\\color{black}{}", + "\\Gd": "\\color{green}{G_d}\\color{black}{}", + + "\\Ivpkappd": "\\color{violet}{Ivpk_{app,d}}\\color{black}{}", + "\\shareableIvpkappd": + "\\color{violet}{\\widetilde{Ivpk_{app,d}}}\\color{black}{}", + "\\Ivpkmd": "\\color{violet}{Ivpk_{m,d}}\\color{black}{}", + "\\shareableIvpkmd": + "\\color{violet}{\\widetilde{Ivpk_{m,d}}}\\color{black}{}", + + "\\ivskappstealth": "\\color{red}{ivsk_{app,stealth}}\\color{black}{}", + "\\Ivpkappdstealth": "\\color{violet}{Ivpk_{app,d,stealth}}\\color{black}{}", + "\\Pkappdstealth": "\\color{violet}{Pk_{app,d,stealth}}\\color{black}{}", + "\\ivskmstealth": "\\color{red}{ivsk_{m,stealth}}\\color{black}{}", + "\\Ivpkmdstealth": "\\color{violet}{Ivpk_{m,d,stealth}}\\color{black}{}", + "\\Pkmdstealth": "\\color{violet}{Pk_{m,d,stealth}}\\color{black}{}", + + "\\hstealth": "\\color{violet}{h_{stealth}}\\color{black}{}", + + "\\esk": "\\color{red}{esk}\\color{black}{}", + "\\Epk": "\\color{green}{Epk}\\color{black}{}", + "\\Epkd": "\\color{green}{Epk_d}\\color{black}{}", + "\\eskheader": "\\color{red}{esk_{header}}\\color{black}{}", + "\\Epkheader": "\\color{green}{Epk_{header}}\\color{black}{}", + "\\Epkdheader": "\\color{green}{Epk_{d,header}}\\color{black}{}", + + "\\sharedsecret": "\\color{violet}{\\text{S}}\\color{black}{}", + "\\sharedsecretmheader": + "\\color{violet}{\\text{S_{m,header}}}\\color{black}{}", + "\\sharedsecretappheader": + "\\color{violet}{\\text{S_{app,header}}}\\color{black}{}", + + "\\hmencheader": "\\color{violet}{h_{m,enc,header}}\\color{black}{}", + "\\happencheader": "\\color{violet}{h_{app,enc,header}}\\color{black}{}", + "\\hmenc": "\\color{violet}{h_{m,enc}}\\color{black}{}", + "\\happenc": "\\color{violet}{h_{app,enc}}\\color{black}{}", + "\\incomingenckey": "\\color{violet}{h_{incoming_enc_key}}\\color{black}{}", + + "\\plaintext": "\\color{red}{\\text{plaintext}}\\color{black}{}", + "\\ciphertext": "\\color{green}{\\text{ciphertext}}\\color{black}{}", + "\\ciphertextheader": + "\\color{green}{\\text{ciphertext\\_header}}\\color{black}{}", + "\\payload": "\\color{green}{\\text{payload}}\\color{black}{}", + + "\\tagg": "\\color{green}{\\text{tag}}\\color{black}{}", + "\\Taghs": "\\color{green}{\\text{Tag}\\_{hs}}\\color{black}{}", +}; diff --git a/docs/src/preprocess/InstructionSet/InstructionSet.js b/docs/src/preprocess/InstructionSet/InstructionSet.js new file mode 100644 index 000000000000..496b2a8128d7 --- /dev/null +++ b/docs/src/preprocess/InstructionSet/InstructionSet.js @@ -0,0 +1,1605 @@ +const { instructionSize } = require("./InstructionSize"); + +const TOPICS_IN_TABLE = ["Name", "Summary", "Expression"]; +const TOPICS_IN_SECTIONS = [ + "Name", + "Summary", + "Category", + "Flags", + "Args", + "Expression", + "Details", + "World State access tracing", + "Additional AVM circuit checks", + "Triggers downstream circuit operations", + "Tag checks", + "Tag updates", + "Bit-size", +]; + +const IN_TAG_DESCRIPTION = + "The [tag/size](./memory-model#tags-and-tagged-memory) to check inputs against and tag the destination with."; +const IN_TAG_DESCRIPTION_NO_FIELD = + IN_TAG_DESCRIPTION + " `field` type is NOT supported for this instruction."; +const DST_TAG_DESCRIPTION = + "The [tag/size](./memory-model#tags-and-tagged-memory) to tag the destination with but not to check inputs against."; +const INDIRECT_FLAG_DESCRIPTION = + "Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`."; + +const CALL_INSTRUCTION_ARGS = [ + { + name: "gasOffset", + description: + "offset to three words containing `{l1GasLeft, l2GasLeft, daGasLeft}`: amount of gas to provide to the callee", + }, + { name: "addrOffset", description: "address of the contract to call" }, + { + name: "argsOffset", + description: "memory offset to args (will become the callee's calldata)", + }, + { + name: "argsSizeOffset", + description: + "memory offset for the number of words to pass via callee's calldata", + }, + { + name: "retOffset", + description: + "destination memory offset specifying where to store the data returned from the callee", + }, + { + name: "retSize", + description: "number of words to copy from data returned by callee", + mode: "immediate", + type: "u32", + }, + { + name: "successOffset", + description: + "destination memory offset specifying where to store the call's success (0: failure, 1: success)", + type: "u8", + }, +]; +const CALL_INSTRUCTION_DETAILS = ` + ["Nested contract calls"](./nested-calls) provides a full explanation of this + instruction along with the shorthand used in the expression above. + The explanation includes details on charging gas for nested calls, + nested context derivation, world state tracing, and updating the parent context + after the nested call halts.`; + +const INSTRUCTION_SET_RAW = [ + { + id: "add", + Name: "`ADD`", + Category: "Compute - Arithmetic", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] + M[bOffset] mod 2^k`", + Summary: "Addition (a + b)", + Details: "Wraps on overflow", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "sub", + Name: "`SUB`", + Category: "Compute - Arithmetic", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] - M[bOffset] mod 2^k`", + Summary: "Subtraction (a - b)", + Details: "Wraps on undeflow", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "mul", + Name: "`MUL`", + Category: "Compute - Arithmetic", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] * M[bOffset] mod 2^k`", + Summary: "Multiplication (a * b)", + Details: "Wraps on overflow", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "div", + Name: "`DIV`", + Category: "Compute - Arithmetic", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] / M[bOffset]`", + Summary: "Unsigned integer division (a / b)", + Details: "If the input is a field, it will be interpreted as an integer", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "fdiv", + Name: "`FDIV`", + Category: "Compute - Arithmetic", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] / M[bOffset]`", + Summary: "Field division (a / b)", + Details: "", + "Tag checks": "`T[aOffset] == T[bOffset] == field`", + "Tag updates": "`T[dstOffset] = field`", + }, + { + id: "eq", + Name: "`EQ`", + Category: "Compute - Comparators", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + type: "u8", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] == M[bOffset] ? 1 : 0`", + Summary: "Equality check (a == b)", + Details: "", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = u8`", + }, + { + id: "lt", + Name: "`LT`", + Category: "Compute - Comparators", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + type: "u8", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] < M[bOffset] ? 1 : 0`", + Summary: "Less-than check (a < b)", + Details: "", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = u8`", + }, + { + id: "lte", + Name: "`LTE`", + Category: "Compute - Comparators", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + type: "u8", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] <= M[bOffset] ? 1 : 0`", + Summary: "Less-than-or-equals check (a <= b)", + Details: "", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = u8`", + }, + { + id: "and", + Name: "`AND`", + Category: "Compute - Bitwise", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION_NO_FIELD }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] AND M[bOffset]`", + Summary: "Bitwise AND (a & b)", + Details: "", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "or", + Name: "`OR`", + Category: "Compute - Bitwise", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION_NO_FIELD }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] OR M[bOffset]`", + Summary: "Bitwise OR (a | b)", + Details: "", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "xor", + Name: "`XOR`", + Category: "Compute - Bitwise", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION_NO_FIELD }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] XOR M[bOffset]`", + Summary: "Bitwise XOR (a ^ b)", + Details: "", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "not", + Name: "`NOT`", + Category: "Compute - Bitwise", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION_NO_FIELD }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = NOT M[aOffset]`", + Summary: "Bitwise NOT (inversion)", + Details: "", + "Tag checks": "`T[aOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "shl", + Name: "`SHL`", + Category: "Compute - Bitwise", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION_NO_FIELD }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] << M[bOffset]`", + Summary: "Bitwise leftward shift (a << b)", + Details: "", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "shr", + Name: "`SHR`", + Category: "Compute - Bitwise", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "inTag", description: IN_TAG_DESCRIPTION_NO_FIELD }, + ], + Args: [ + { + name: "aOffset", + description: "memory offset of the operation's left input", + }, + { + name: "bOffset", + description: "memory offset of the operation's right input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[aOffset] >> M[bOffset]`", + Summary: "Bitwise rightward shift (a >> b)", + Details: "", + "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "cast", + Name: "`CAST`", + Category: "Type Conversions", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { name: "dstTag", description: DST_TAG_DESCRIPTION }, + ], + Args: [ + { name: "aOffset", description: "memory offset of word to cast" }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = cast(M[aOffset])`", + Summary: "Type cast", + Details: + "Cast a word in memory based on the `dstTag` specified in the bytecode. Truncates (`M[dstOffset] = M[aOffset] mod 2^dstsize`) when casting to a smaller type, left-zero-pads when casting to a larger type. See [here](./memory-model#cast-and-tag-conversions) for more details.", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = dstTag`", + }, + { + id: "address", + Name: "`ADDRESS`", + Category: "Execution Environment", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.address`", + Summary: "Get the address of the currently executing l2 contract", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "storageaddress", + Name: "`STORAGEADDRESS`", + Category: "Execution Environment", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.storageAddress`", + Summary: "Get the _storage_ address of the currently executing context", + Details: "The storage address is used for public storage accesses.", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "sender", + Name: "`SENDER`", + Category: "Execution Environment", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.sender`", + Summary: "Get the address of the sender (caller of the current context)", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "portal", + Name: "`PORTAL`", + Category: "Execution Environment", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.portal`", + Summary: "Get the address of the l1 portal contract", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "feeperl1gas", + Name: "`FEEPERL1GAS`", + Category: "Execution Environment", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.feePerL1Gas`", + Summary: + 'Get the fee to be paid per "L1 gas" - constant for entire transaction', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "feeperl2gas", + Name: "`FEEPERL2GAS`", + Category: "Execution Environment", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.feePerL2Gas`", + Summary: + 'Get the fee to be paid per "L2 gas" - constant for entire transaction', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "feeperdagas", + Name: "`FEEPERDAGAS`", + Category: "Execution Environment", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.feePerDaGas`", + Summary: + 'Get the fee to be paid per "DA gas" - constant for entire transaction', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "contractcalldepth", + Name: "`CONTRACTCALLDEPTH`", + Category: "Execution Environment", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.contractCallDepth`", + Summary: "Get how many contract calls deep the current call context is", + Details: + "Note: security issues with EVM's tx.origin can be resolved by asserting `calldepth == 0`.", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u8`", + }, + { + id: "chainid", + Name: "`CHAINID`", + Category: "Execution Environment - Globals", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.chainId`", + Summary: "Get this rollup's L1 chain ID", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "version", + Name: "`VERSION`", + Category: "Execution Environment - Globals", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.version`", + Summary: "Get this rollup's L2 version ID", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "blocknumber", + Name: "`BLOCKNUMBER`", + Category: "Execution Environment - Globals", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.blocknumber`", + Summary: "Get this L2 block's number", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "timestamp", + Name: "`TIMESTAMP`", + Category: "Execution Environment - Globals", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.timestamp`", + Summary: "Get this L2 block's timestamp", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u64`", + }, + { + id: "coinbase", + Name: "`COINBASE`", + Category: "Execution Environment - Globals", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.coinbase`", + Summary: "Get the block's beneficiary address", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "blockl1gaslimit", + Name: "`BLOCKL1GASLIMIT`", + Category: "Execution Environment - Globals", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.l1GasLimit`", + Summary: 'Total amount of "L1 gas" that a block can consume', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "blockl2gaslimit", + Name: "`BLOCKL2GASLIMIT`", + Category: "Execution Environment - Globals", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.l2GasLimit`", + Summary: 'Total amount of "L2 gas" that a block can consume', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "blockdagaslimit", + Name: "`BLOCKDAGASLIMIT`", + Category: "Execution Environment - Globals", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.daGasLimit`", + Summary: 'Total amount of "DA gas" that a block can consume', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "calldatacopy", + Name: "`CALLDATACOPY`", + Category: "Execution Environment - Calldata", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { name: "cdOffset", description: "offset into calldata to copy from" }, + { + name: "copySize", + description: "number of words to copy", + mode: "immediate", + type: "u32", + }, + { + name: "dstOffset", + description: "memory offset specifying where to copy the first word to", + }, + ], + Expression: + "`M[dstOffset:dstOffset+copySize] = context.environment.calldata[cdOffset:cdOffset+copySize]`", + Summary: "Copy calldata into memory", + Details: + "Calldata is read-only and cannot be directly operated on by other instructions. This instruction moves words from calldata into memory so they can be operated on normally.", + "Tag checks": "", + "Tag updates": "`T[dstOffset:dstOffset+copySize] = field`", + }, + { + id: "l1gasleft", + Name: "`L1GASLEFT`", + Category: "Machine State - Gas", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.machineState.l1GasLeft`", + Summary: 'Remaining "L1 gas" for this call (after this instruction)', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "l2gasleft", + Name: "`L2GASLEFT`", + Category: "Machine State - Gas", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.MachineState.l2GasLeft`", + Summary: 'Remaining "L2 gas" for this call (after this instruction)', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "dagasleft", + Name: "`DAGASLEFT`", + Category: "Machine State - Gas", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.machineState.daGasLeft`", + Summary: 'Remaining "DA gas" for this call (after this instruction)', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + id: "jump", + Name: "`JUMP`", + Category: "Machine State - Control Flow", + Flags: [], + Args: [ + { + name: "loc", + description: "target location to jump to", + mode: "immediate", + type: "u32", + }, + ], + Expression: "`context.machineState.pc = loc`", + Summary: "Jump to a location in the bytecode", + Details: + "Target location is an immediate value (a constant in the bytecode).", + "Tag checks": "", + "Tag updates": "", + }, + { + id: "jumpi", + Name: "`JUMPI`", + Category: "Machine State - Control Flow", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "loc", + description: "target location conditionally jump to", + mode: "immediate", + type: "u32", + }, + { + name: "condOffset", + description: "memory offset of the operations 'conditional' input", + }, + ], + Expression: + "`context.machineState.pc = M[condOffset] > 0 ? loc : context.machineState.pc`", + Summary: "Conditionally jump to a location in the bytecode", + Details: + "Target location is an immediate value (a constant in the bytecode). `T[condOffset]` is not checked because the greater-than-zero suboperation is the same regardless of type.", + "Tag checks": "", + "Tag updates": "", + }, + { + id: "internalcall", + Name: "`INTERNALCALL`", + Category: "Machine State - Control Flow", + Flags: [], + Args: [ + { + name: "loc", + description: "target location to jump/call to", + mode: "immediate", + type: "u32", + }, + ], + Expression: ` +context.machineState.internalCallStack.push(context.machineState.pc) +context.machineState.pc = loc +`, + Summary: + "Make an internal call. Push the current PC to the internal call stack and jump to the target location.", + Details: + "Target location is an immediate value (a constant in the bytecode).", + "Tag checks": "", + "Tag updates": "", + }, + { + id: "internalreturn", + Name: "`INTERNALRETURN`", + Category: "Machine State - Control Flow", + Flags: [], + Args: [], + Expression: + "`context.machineState.pc = context.machineState.internalCallStack.pop()`", + Summary: + "Return from an internal call. Pop from the internal call stack and jump to the popped location.", + Details: "", + "Tag checks": "", + "Tag updates": "", + }, + { + id: "set", + Name: "`SET`", + Category: "Machine State - Memory", + Flags: [ + { name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }, + { + name: "inTag", + description: + "The [type/size](./memory-model#tags-and-tagged-memory) to check inputs against and tag the destination with. `field` type is NOT supported for SET.", + }, + ], + Args: [ + { + name: "const", + description: + "an N-bit constant value from the bytecode to store in memory (any type except `field`)", + mode: "immediate", + }, + { + name: "dstOffset", + description: "memory offset specifying where to store the constant", + }, + ], + Expression: "`M[dstOffset] = const`", + Summary: "Set a memory word from a constant in the bytecode", + Details: + "Set memory word at `dstOffset` to `const`'s immediate value. `const`'s bit-size (N) can be 8, 16, 32, 64, or 128 based on `inTag`. It _cannot be 254 (`field` type)_!", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = inTag`", + }, + { + id: "mov", + Name: "`MOV`", + Category: "Machine State - Memory", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { name: "srcOffset", description: "memory offset of word to move" }, + { + name: "dstOffset", + description: "memory offset specifying where to store that word", + }, + ], + Expression: "`M[dstOffset] = M[srcOffset]`", + Summary: "Move a word from source memory location to destination", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = T[srcOffset]`", + }, + { + id: "cmov", + Name: "`CMOV`", + Category: "Machine State - Memory", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "aOffset", + description: "memory offset of word 'a' to conditionally move", + }, + { + name: "bOffset", + description: "memory offset of word 'b' to conditionally move", + }, + { + name: "condOffset", + description: "memory offset of the operations 'conditional' input", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = M[condOffset] > 0 ? M[aOffset] : M[bOffset]`", + Summary: + "Move a word (conditionally chosen) from one memory location to another (`d = cond > 0 ? a : b`)", + Details: + "One of two source memory locations is chosen based on the condition. `T[condOffset]` is not checked because the greater-than-zero suboperation is the same regardless of type.", + "Tag checks": "", + "Tag updates": + "`T[dstOffset] = M[condOffset] > 0 ? T[aOffset] : T[bOffset]`", + }, + { + id: "sload", + Name: "`SLOAD`", + Category: "World State - Public Storage", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "slotOffset", + description: "memory offset of the storage slot to load from", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: ` +M[dstOffset] = S[M[slotOffset]] +`, + Summary: + "Load a word from this contract's persistent public storage. Zero is loaded for unwritten slots.", + Details: ` +// Expression is shorthand for +leafIndex = hash(context.environment.storageAddress, M[slotOffset]) +exists = context.worldState.publicStorage.has(leafIndex) // exists == previously-written +if exists: + value = context.worldState.publicStorage.get(leafIndex: leafIndex) +else: + value = 0 +M[dstOffset] = value +`, + "World State access tracing": ` +context.worldStateAccessTrace.publicStorageReads.append( + TracedStorageRead { + callPointer: context.environment.callPointer, + slot: M[slotOffset], + exists: exists, // defined above + value: value, // defined above + counter: ++context.worldStateAccessTrace.accessCounter, + } +) +`, + "Triggers downstream circuit operations": + "Storage slot siloing (hash with contract address), public data tree membership check", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + id: "sstore", + Name: "`SSTORE`", + Category: "World State - Public Storage", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { name: "srcOffset", description: "memory offset of the word to store" }, + { + name: "slotOffset", + description: "memory offset containing the storage slot to store to", + }, + ], + Expression: ` +S[M[slotOffset]] = M[srcOffset] +`, + Summary: "Write a word to this contract's persistent public storage", + Details: ` +// Expression is shorthand for +context.worldState.publicStorage.set({ + leafIndex: hash(context.environment.storageAddress, M[slotOffset]), + leaf: M[srcOffset], +}) +`, + "World State access tracing": ` +context.worldStateAccessTrace.publicStorageWrites.append( + TracedStorageWrite { + callPointer: context.environment.callPointer, + slot: M[slotOffset], + value: M[srcOffset], + counter: ++context.worldStateAccessTrace.accessCounter, + } +) +`, + "Triggers downstream circuit operations": + "Storage slot siloing (hash with contract address), public data tree update", + "Tag checks": "", + "Tag updates": "", + }, + { + id: "notehashexists", + Name: "`NOTEHASHEXISTS`", + Category: "World State - Notes & Nullifiers", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { name: "noteHashOffset", description: "memory offset of the note hash" }, + { + name: "leafIndexOffset", + description: "memory offset of the leaf index", + }, + { + name: "existsOffset", + description: + "memory offset specifying where to store operation's result (whether the note hash leaf exists)", + }, + ], + Expression: ` +exists = context.worldState.noteHashes.has({ + leafIndex: M[leafIndexOffset] + leaf: hash(context.environment.storageAddress, M[noteHashOffset]), +}) +M[existsOffset] = exists +`, + Summary: + "Check whether a note hash exists in the note hash tree (as of the start of the current block)", + "World State access tracing": ` +context.worldStateAccessTrace.noteHashChecks.append( + TracedNoteHashCheck { + callPointer: context.environment.callPointer, + leafIndex: M[leafIndexOffset] + noteHash: M[noteHashOffset], + exists: exists, // defined above + counter: ++context.worldStateAccessTrace.accessCounter, + } +) +`, + "Triggers downstream circuit operations": + "Note hash siloing (hash with storage contract address), note hash tree membership check", + "Tag checks": "", + "Tag updates": "`T[existsOffset] = u8`", + }, + { + id: "emitnotehash", + Name: "`EMITNOTEHASH`", + Category: "World State - Notes & Nullifiers", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { name: "noteHashOffset", description: "memory offset of the note hash" }, + ], + Expression: ` +context.worldState.noteHashes.append( + hash(context.environment.storageAddress, M[noteHashOffset]) +) +`, + Summary: "Emit a new note hash to be inserted into the note hash tree", + "World State access tracing": ` +context.worldStateAccessTrace.newNoteHashes.append( + TracedNoteHash { + callPointer: context.environment.callPointer, + noteHash: M[noteHashOffset], // unsiloed note hash + counter: ++context.worldStateAccessTrace.accessCounter, + } +) +`, + "Triggers downstream circuit operations": + "Note hash siloing (hash with contract address), note hash tree insertion.", + "Tag checks": "", + "Tag updates": "", + }, + { + id: "nullifierexists", + Name: "`NULLIFIEREXISTS`", + Category: "World State - Notes & Nullifiers", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "nullifierOffset", + description: "memory offset of the unsiloed nullifier", + }, + { + name: "addressOffset", + description: "memory offset of the storage address", + }, + { + name: "existsOffset", + description: + "memory offset specifying where to store operation's result (whether the nullifier exists)", + }, + ], + Expression: ` +exists = pendingNullifiers.has(M[addressOffset], M[nullifierOffset]) || context.worldState.nullifiers.has( + hash(M[addressOffset], M[nullifierOffset]) +) +M[existsOffset] = exists +`, + Summary: + "Check whether a nullifier exists in the nullifier tree (including nullifiers from earlier in the current transaction or from earlier in the current block)", + "World State access tracing": ` +context.worldStateAccessTrace.nullifierChecks.append( + TracedNullifierCheck { + callPointer: context.environment.callPointer, + nullifier: M[nullifierOffset], + storageAddress: M[addressOffset], + exists: exists, // defined above + counter: ++context.worldStateAccessTrace.accessCounter, + } +) +`, + "Triggers downstream circuit operations": + "Nullifier siloing (hash with storage contract address), nullifier tree membership check", + "Tag checks": "", + "Tag updates": "`T[existsOffset] = u8`", + }, + { + id: "emitnullifier", + Name: "`EMITNULLIFIER`", + Category: "World State - Notes & Nullifiers", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { name: "nullifierOffset", description: "memory offset of nullifier" }, + ], + Expression: ` +context.worldState.nullifiers.append( + hash(context.environment.storageAddress, M[nullifierOffset]) +) +`, + Summary: "Emit a new nullifier to be inserted into the nullifier tree", + "World State access tracing": ` +context.worldStateAccessTrace.newNullifiers.append( + TracedNullifier { + callPointer: context.environment.callPointer, + nullifier: M[nullifierOffset], // unsiloed nullifier + counter: ++context.worldStateAccessTrace.accessCounter, + } +) +`, + "Triggers downstream circuit operations": + "Nullifier siloing (hash with contract address), nullifier tree non-membership-check and insertion.", + "Tag checks": "", + "Tag updates": "", + }, + { + id: "l1tol2msgexists", + Name: "`L1TOL2MSGEXISTS`", + Category: "World State - Messaging", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "msgHashOffset", + description: "memory offset of the message hash", + }, + { + name: "msgLeafIndexOffset", + description: + "memory offset of the message's leaf index in the L1-to-L2 message tree", + }, + { + name: "existsOffset", + description: + "memory offset specifying where to store operation's result (whether the message exists in the L1-to-L2 message tree)", + }, + ], + Expression: ` +exists = context.worldState.l1ToL2Messages.has({ + leafIndex: M[msgLeafIndexOffset], leaf: M[msgHashOffset] +}) +M[existsOffset] = exists +`, + Summary: "Check if a message exists in the L1-to-L2 message tree", + "World State access tracing": ` +context.worldStateAccessTrace.l1ToL2MessagesChecks.append( + L1ToL2Message { + callPointer: context.environment.callPointer, + leafIndex: M[msgLeafIndexOffset], + msgHash: M[msgHashOffset], + exists: exists, // defined above + } +) +`, + "Triggers downstream circuit operations": + "L1-to-L2 message tree membership check", + "Tag checks": "", + "Tag updates": ` +T[existsOffset] = u8, +`, + }, + { + id: "headermember", + Name: "`HEADERMEMBER`", + Category: "World State - Archive Tree & Headers", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "blockIndexOffset", + description: + "memory offset of the block index (same as archive tree leaf index) of the header to access", + }, + { + name: "memberIndexOffset", + description: + "memory offset of the index of the member to retrieve from the header of the specified block", + }, + { + name: "existsOffset", + description: + "memory offset specifying where to store operation's result (whether the leaf exists in the archive tree)", + }, + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result (the retrieved header member)", + }, + ], + Expression: ` +exists = context.worldState.header.has({ + leafIndex: M[blockIndexOffset], leaf: M[msgKeyOffset] +}) +M[existsOffset] = exists +if exists: + header = context.worldState.headers.get(M[blockIndexOffset]) + M[dstOffset] = header[M[memberIndexOffset]] // member +`, + Summary: + "Check if a header exists in the [archive tree](../state/archive) and retrieve the specified member if so", + "World State access tracing": ` +context.worldStateAccessTrace.archiveChecks.append( + TracedArchiveLeafCheck { + leafIndex: M[blockIndexOffset], // leafIndex == blockIndex + leaf: exists ? hash(header) : 0, // "exists" defined above + } +) +`, + "Additional AVM circuit checks": + "Hashes entire header to archive leaf for tracing. Aggregates header accesses and so that a header need only be hashed once.", + "Triggers downstream circuit operations": "Archive tree membership check", + "Tag checks": "", + "Tag updates": ` +T[existsOffset] = u8 +T[dstOffset] = field +`, + }, + { + id: "getcontractinstance", + Name: "`GETCONTRACTINSTANCE`", + Category: "Other", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "addressOffset", + description: "memory offset of the contract instance address", + }, + { + name: "dstOffset", + description: "location to write the contract instance information to", + }, + ], + Expression: ` +M[dstOffset:dstOffset+CONTRACT_INSTANCE_SIZE+1] = [ + instance_found_in_address, + instance.salt ?? 0, + instance.deployer ?? 0, + instance.contractClassId ?? 0, + instance.initializationHash ?? 0, + instance.portalContractAddress ?? 0, + instance.publicKeysHash ?? 0, +] +`, + Summary: "Copies contract instance data to memory", + "Tag checks": "", + "Tag updates": "T[dstOffset:dstOffset+CONTRACT_INSTANCE_SIZE+1] = field", + "Additional AVM circuit checks": "TO-DO", + "Triggers downstream circuit operations": "TO-DO", + }, + { + id: "emitunencryptedlog", + Name: "`EMITUNENCRYPTEDLOG`", + Category: "Accrued Substate - Logging", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "eventSelectorOffset", + description: "memory offset of the event selector", + }, + { name: "logOffset", description: "memory offset of the data to log" }, + { + name: "logSize", + description: "number of words to log", + mode: "immediate", + type: "u32", + }, + ], + Expression: ` +context.accruedSubstate.unencryptedLogs.append( + UnencryptedLog { + address: context.environment.address, + eventSelector: M[eventSelectorOffset], + log: M[logOffset:logOffset+logSize], + } +) +`, + Summary: "Emit an unencrypted log", + "Tag checks": "", + "Tag updates": "", + }, + { + id: "sendl2tol1msg", + Name: "`SENDL2TOL1MSG`", + Category: "Accrued Substate - Messaging", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "recipientOffset", + description: "memory offset of the message recipient", + }, + { + name: "contentOffset", + description: "memory offset of the message content", + }, + ], + Expression: ` +context.accruedSubstate.sentL2ToL1Messages.append( + SentL2ToL1Message { + address: context.environment.address, + recipient: M[recipientOffset], + message: M[contentOffset] + } +) +`, + Summary: "Send an L2-to-L1 message", + "Tag checks": "", + "Tag updates": "", + }, + { + id: "call", + Name: "`CALL`", + Category: "Control Flow - Contract Calls", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: CALL_INSTRUCTION_ARGS, + Expression: ` +// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } +chargeGas(context, + l1GasCost=M[instr.args.gasOffset], + l2GasCost=M[instr.args.gasOffset+1], + daGasCost=M[instr.args.gasOffset+2]) +traceNestedCall(context, instr.args.addrOffset) +nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=false) +execute(nestedContext) +updateContextAfterNestedCall(context, instr.args, nestedContext) +`, + Summary: "Call into another contract", + Details: + `Creates a new (nested) execution context and triggers execution within that context. + Execution proceeds in the nested context until it reaches a halt at which point + execution resumes in the current/calling context. + A non-existent contract or one with no code will return success. ` + + CALL_INSTRUCTION_DETAILS, + "Tag checks": "`T[gasOffset] == T[gasOffset+1] == T[gasOffset+2] == u32`", + "Tag updates": ` +T[successOffset] = u8 +T[retOffset:retOffset+retSize] = field +`, + }, + { + id: "staticcall", + Name: "`STATICCALL`", + Category: "Control Flow - Contract Calls", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: CALL_INSTRUCTION_ARGS, + Expression: ` +// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } +chargeGas(context, + l1GasCost=M[instr.args.gasOffset], + l2GasCost=M[instr.args.gasOffset+1], + daGasCost=M[instr.args.gasOffset+2]) +traceNestedCall(context, instr.args.addrOffset) +nestedContext = deriveContext(context, instr.args, isStaticCall=true, isDelegateCall=false) +execute(nestedContext) +updateContextAfterNestedCall(context, instr.args, nestedContext) +`, + Summary: + "Call into another contract, disallowing World State and Accrued Substate modifications", + Details: + `Same as \`CALL\`, but disallows World State and Accrued Substate modifications. ` + + CALL_INSTRUCTION_DETAILS, + "Tag checks": "`T[gasOffset] == T[gasOffset+1] == T[gasOffset+2] == u32`", + "Tag updates": ` +T[successOffset] = u8 +T[retOffset:retOffset+retSize] = field +`, + }, + { + id: "delegatecall", + Name: "`DELEGATECALL`", + Category: "Control Flow - Contract Calls", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: CALL_INSTRUCTION_ARGS, + Expression: ` +// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } +chargeGas(context, + l1GasCost=M[instr.args.gasOffset], + l2GasCost=M[instr.args.gasOffset+1], + daGasCost=M[instr.args.gasOffset+2]) +traceNestedCall(context, instr.args.addrOffset) +nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=true) +execute(nestedContext) +updateContextAfterNestedCall(context, instr.args, nestedContext) +`, + Summary: + "Call into another contract, but keep the caller's `sender` and `storageAddress`", + Details: + `Same as \`CALL\`, but \`sender\` and \`storageAddress\` remains + the same in the nested call as they were in the caller. ` + + CALL_INSTRUCTION_DETAILS, + "Tag checks": "`T[gasOffset] == T[gasOffset+1] == T[gasOffset+2] == u32`", + "Tag updates": ` +T[successOffset] = u8 +T[retOffset:retOffset+retSize] = field +`, + }, + { + id: "return", + Name: "`RETURN`", + Category: "Control Flow - Contract Calls", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "retOffset", + description: "memory offset of first word to return", + }, + { + name: "retSize", + description: "number of words to return", + mode: "immediate", + type: "u32", + }, + ], + Expression: ` +context.contractCallResults.output = M[retOffset:retOffset+retSize] +halt +`, + Summary: + "Halt execution within this context (without revert), optionally returning some data", + Details: + 'Return control flow to the calling context/contract. Caller will accept World State and Accrued Substate modifications. See ["Halting"](./execution#halting) to learn more. See ["Nested contract calls"](./nested-calls) to see how the caller updates its context after the nested call halts.', + "Tag checks": "", + "Tag updates": "", + }, + { + id: "revert", + Name: "`REVERT`", + Category: "Control Flow - Contract Calls", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "retOffset", + description: "memory offset of first word to return", + }, + { + name: "retSize", + description: "number of words to return", + mode: "immediate", + type: "u32", + }, + ], + Expression: ` +context.contractCallResults.output = M[retOffset:retOffset+retSize] +context.contractCallResults.reverted = true +halt +`, + Summary: + "Halt execution within this context as `reverted`, optionally returning some data", + Details: + 'Return control flow to the calling context/contract. Caller will reject World State and Accrued Substate modifications. See ["Halting"](./execution#halting) to learn more. See ["Nested contract calls"](./nested-calls) to see how the caller updates its context after the nested call halts.', + "Tag checks": "", + "Tag updates": "", + }, +]; +const INSTRUCTION_SET = INSTRUCTION_SET_RAW.map((instr) => { + instr["Bit-size"] = instructionSize(instr); + return instr; +}); + +module.exports = { + TOPICS_IN_TABLE, + TOPICS_IN_SECTIONS, + INSTRUCTION_SET, +}; diff --git a/yellow-paper/src/preprocess/InstructionSet/InstructionSize.js b/docs/src/preprocess/InstructionSet/InstructionSize.js similarity index 100% rename from yellow-paper/src/preprocess/InstructionSet/InstructionSize.js rename to docs/src/preprocess/InstructionSet/InstructionSize.js diff --git a/yellow-paper/src/preprocess/InstructionSet/genBitFormats.js b/docs/src/preprocess/InstructionSet/genBitFormats.js similarity index 100% rename from yellow-paper/src/preprocess/InstructionSet/genBitFormats.js rename to docs/src/preprocess/InstructionSet/genBitFormats.js diff --git a/docs/src/preprocess/InstructionSet/genMarkdown.js b/docs/src/preprocess/InstructionSet/genMarkdown.js new file mode 100644 index 000000000000..c67b7fd08fa7 --- /dev/null +++ b/docs/src/preprocess/InstructionSet/genMarkdown.js @@ -0,0 +1,162 @@ +const fs = require("fs"); +const path = require("path"); + +const { + TOPICS_IN_TABLE, + TOPICS_IN_SECTIONS, + INSTRUCTION_SET, + instructionSize, +} = require("./InstructionSet"); + +function escapeBraces(str) { + return str.replace(//g, ">"); +} + +function stripBraces(str) { + return str.replace(/[<>]/g, ""); +} + +function instructionSetPreface() { + let preface = "[comment]: # (THIS IS A GENERATED FILE! DO NOT EDIT!)\n"; + preface += "[comment]: # (Generated via `yarn preprocess`)\n\n"; + preface += + "[comment]: # (Generated by genMarkdown.js, InstructionSet.js, InstructionSize.js)\n\n"; + preface += "import Markdown from 'react-markdown'\n"; + preface += "import CodeBlock from '@theme/CodeBlock'\n\n"; + return preface; +} + +function toOpcode(index) { + return "0x" + index.toString(16).padStart(2, "0"); +} + +function htmlInstructionSetTable() { + let table = "## Instructions Table\n"; + table += "\nClick on an instruction name to jump to its section.\n"; + table += "\n\n"; + let header = ""; + for (let t = 0; t < TOPICS_IN_TABLE.length; t++) { + header += ``; + } + table += `${header}\n`; + + for (let i = 0; i < INSTRUCTION_SET.length; i++) { + const instr = INSTRUCTION_SET[i]; + const name = instr["Name"]; + let row = `\n`; + row += `\t`; + row += `\t`; + + for (let t = 0; t < TOPICS_IN_TABLE.length; t++) { + const topic = TOPICS_IN_TABLE[t]; + + if (topic == "Name") continue; // skip + let cell = instr[topic]; + if (cell[0] == "\n") { + // if string starts with newline, assume it's a multi-line code block + cell = `\n{\`${cell.trim()}\`}\n\t`; + } else if (cell[0] == "`" && topic != "Name") { + cell = `{\n\t\t\`${cell.replace( + /`/g, + "" + )}\`\n\t}`; + } else { + cell = escapeBraces(cell); // escape html + cell = `${cell}`; + } + row += `\n\t`; + } + row += "\n"; + table += `${row}\n`; + } + table += "
Opcode${TOPICS_IN_TABLE[t]}
${toOpcode(i)}[${stripBraces(name)}](#isa-section-${ + instr["id"] + })${cell}
\n"; + return table; +} + +function markdownSublist(items) { + let markdown = ""; + for (let i = 0; i < items.length; i++) { + let item = items[i]; + if (typeof item === "string") { + markdown += `\n\t- ${item}`; + } else { + markdown += `\n\t- **${item["name"]}**: ${item["description"]}`; + } + } + return markdown; +} + +function markdownInstructionSetSection(docsDir) { + let markdown = "## Instructions\n"; + for (let i = 0; i < INSTRUCTION_SET.length; i++) { + const instr = INSTRUCTION_SET[i]; + const name = instr["Name"]; + let subsection = `### ${name}\n`; + subsection += `${instr["Summary"]}\n\n`; + subsection += `[See in table.](#isa-table-${instr["id"]})\n\n`; + subsection += `- **Opcode**: ${toOpcode(i)}\n`; + for (let t = 0; t < TOPICS_IN_SECTIONS.length; t++) { + const topic = TOPICS_IN_SECTIONS[t]; + let field = instr[topic]; + if (topic == "Name" || topic == "Summary" || !field || field.length == 0) + continue; // skip + + let item = `- **${topic}**: `; + if (Array.isArray(field)) { + item += markdownSublist(field); + } else if (field[0] == "\n") { + // if string starts with newline, assume it's a multi-line code block + item += `\n\n{\`${field.trim()}\`}\n`; + } else { + item += field; + } + subsection += `${item}\n`; + } + + // docusaurus will get images from static/img + const urlPath = `/img/protocol-specs/public-vm/bit-formats/${name.replace( + /`/g, + "" + )}.png`; + + const bitFormatImagePath = path.join(docsDir, "..", `static${urlPath}`); + + if (fs.existsSync(bitFormatImagePath)) { + subsection += `\n[![](${urlPath})](${urlPath})`; + } + markdown += `\n${subsection}\n`; + } + return markdown; +} + +async function generateInstructionSet() { + const rootDir = path.join(__dirname, "../../../../"); + const docsDir = path.join(rootDir, "docs", "docs"); + + const relPath = path.relative( + docsDir, + "docs/protocol-specs/public-vm/gen/_instruction-set.mdx" + ); + const docsFilePath = path.resolve(docsDir, relPath); + const docsDirName = path.dirname(docsFilePath); + if (!fs.existsSync(docsDirName)) { + fs.mkdirSync(docsDirName, { recursive: true }); + } + + const preface = instructionSetPreface(); + const table = htmlInstructionSetTable(); + + const section = markdownInstructionSetSection(docsDir); + const doc = `${preface}\n${table}\n\n${section}`; + fs.writeFileSync(docsFilePath, doc); + + console.log("Preprocessing complete."); +} + +module.exports = { + generateInstructionSet, +}; diff --git a/docs/src/preprocess/generate_aztecnr_reference.js b/docs/src/preprocess/generate_aztecnr_reference.js index 0d06932453c7..007b952b41df 100644 --- a/docs/src/preprocess/generate_aztecnr_reference.js +++ b/docs/src/preprocess/generate_aztecnr_reference.js @@ -95,7 +95,8 @@ function parseFunctions(content) { } const implBlockContent = content.substring(implMatch.index, currentPos); - const methodRegex = /(?:pub )?fn (\w+)\((.*?)\)(?: -> (.*?))? {/g; + const methodRegex = + /(?:pub\s+)?fn\s+(\w+)(?:<.*?>)?\s*\(([\s\S]*?)\)\s*(?:->\s*(.*?))?\s*{/g; let methodMatch; while ((methodMatch = methodRegex.exec(implBlockContent)) !== null) { @@ -119,7 +120,7 @@ function parseFunctions(content) { } } - const standaloneFunctionRegex = /(?:pub\s+)?fn\s+(\w+)(?:<.*?>)?\s*\((.*?)\)\s*(?:->\s*(.*?))?\s*{/g; + const standaloneFunctionRegex = /(?:pub\s+)?fn\s+(\w+)(?:<.*?>)?\s*\(([\s\S]*?)\)\s*(?:->\s*(.*?))?\s*{/g; let standaloneFunctionMatch; while ((standaloneFunctionMatch = standaloneFunctionRegex.exec(content)) !== null) { const name = standaloneFunctionMatch[1]; diff --git a/docs/src/preprocess/index.js b/docs/src/preprocess/index.js index 129321d4ecde..13b90499ca70 100644 --- a/docs/src/preprocess/index.js +++ b/docs/src/preprocess/index.js @@ -5,6 +5,8 @@ const childProcess = require("child_process"); const { preprocessIncludeCode } = require("./include_code"); const { preprocessIncludeVersion } = require("./include_version"); +const { generateInstructionSet } = require("./InstructionSet/genMarkdown"); + async function processMarkdownFilesInDir(rootDir, docsDir, regex) { const files = fs.readdirSync(docsDir); const contentUpdates = []; @@ -117,6 +119,8 @@ async function writeProcessedFiles(docsDir, destDir, cachedDestDir, content) { } async function run() { + await generateInstructionSet(); + const rootDir = path.join(__dirname, "../../../"); const docsDir = path.join(rootDir, "docs", "docs"); const destDir = path.join(rootDir, "docs", "processed-docs"); diff --git a/yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image-1.png b/docs/static/img/protocol-specs/addresses-and-keys/image-1.png similarity index 100% rename from yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image-1.png rename to docs/static/img/protocol-specs/addresses-and-keys/image-1.png diff --git a/yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image-3.png b/docs/static/img/protocol-specs/addresses-and-keys/image-3.png similarity index 100% rename from yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image-3.png rename to docs/static/img/protocol-specs/addresses-and-keys/image-3.png diff --git a/yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image-4.png b/docs/static/img/protocol-specs/addresses-and-keys/image-4.png similarity index 100% rename from yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image-4.png rename to docs/static/img/protocol-specs/addresses-and-keys/image-4.png diff --git a/yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image-5.png b/docs/static/img/protocol-specs/addresses-and-keys/image-5.png similarity index 100% rename from yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image-5.png rename to docs/static/img/protocol-specs/addresses-and-keys/image-5.png diff --git a/yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image.png b/docs/static/img/protocol-specs/addresses-and-keys/image.png similarity index 100% rename from yellow-paper/docs/addresses-and-keys/images/addresses-and-keys/image.png rename to docs/static/img/protocol-specs/addresses-and-keys/image.png diff --git a/yellow-paper/docs/calls/images/calls/pub_pvt_messaging.png b/docs/static/img/protocol-specs/calls/pub_pvt_messaging.png similarity index 100% rename from yellow-paper/docs/calls/images/calls/pub_pvt_messaging.png rename to docs/static/img/protocol-specs/calls/pub_pvt_messaging.png diff --git a/yellow-paper/docs/calls/images/calls/pvt_pub_ordering.png b/docs/static/img/protocol-specs/calls/pvt_pub_ordering.png similarity index 100% rename from yellow-paper/docs/calls/images/calls/pvt_pub_ordering.png rename to docs/static/img/protocol-specs/calls/pvt_pub_ordering.png diff --git a/yellow-paper/docs/cryptography/images/proof-system-components.png b/docs/static/img/protocol-specs/cryptography/proof-system-components.png similarity index 100% rename from yellow-paper/docs/cryptography/images/proof-system-components.png rename to docs/static/img/protocol-specs/cryptography/proof-system-components.png diff --git a/yellow-paper/docs/decentralization/images/Aztec-Block-Production-1.png b/docs/static/img/protocol-specs/decentralization/Aztec-Block-Production-1.png similarity index 100% rename from yellow-paper/docs/decentralization/images/Aztec-Block-Production-1.png rename to docs/static/img/protocol-specs/decentralization/Aztec-Block-Production-1.png diff --git a/yellow-paper/docs/decentralization/images/Aztec-Block-Production-2.png b/docs/static/img/protocol-specs/decentralization/Aztec-Block-Production-2.png similarity index 100% rename from yellow-paper/docs/decentralization/images/Aztec-Block-Production-2.png rename to docs/static/img/protocol-specs/decentralization/Aztec-Block-Production-2.png diff --git a/yellow-paper/docs/decentralization/images/Aztec-Block-Production-3.png b/docs/static/img/protocol-specs/decentralization/Aztec-Block-Production-3.png similarity index 100% rename from yellow-paper/docs/decentralization/images/Aztec-Block-Production-3.png rename to docs/static/img/protocol-specs/decentralization/Aztec-Block-Production-3.png diff --git a/yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-1.png b/docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-1.png similarity index 100% rename from yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-1.png rename to docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-1.png diff --git a/yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-2.png b/docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-2.png similarity index 100% rename from yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-2.png rename to docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-2.png diff --git a/yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-3.png b/docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-3.png similarity index 100% rename from yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-3.png rename to docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-3.png diff --git a/yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-4.png b/docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-4.png similarity index 100% rename from yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-4.png rename to docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-4.png diff --git a/yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-5.png b/docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-5.png similarity index 100% rename from yellow-paper/docs/decentralization/images/Aztec-Governance-Summary-5.png rename to docs/static/img/protocol-specs/decentralization/Aztec-Governance-Summary-5.png diff --git a/yellow-paper/docs/decentralization/images/network.png b/docs/static/img/protocol-specs/decentralization/network.png similarity index 100% rename from yellow-paper/docs/decentralization/images/network.png rename to docs/static/img/protocol-specs/decentralization/network.png diff --git a/yellow-paper/docs/gas-and-fees/images/gas-and-fees/Transaction.png b/docs/static/img/protocol-specs/gas-and-fees/Transaction.png similarity index 100% rename from yellow-paper/docs/gas-and-fees/images/gas-and-fees/Transaction.png rename to docs/static/img/protocol-specs/gas-and-fees/Transaction.png diff --git a/yellow-paper/docs/l1-smart-contracts/images/com-abs-6.png b/docs/static/img/protocol-specs/l1-smart-contracts/com-abs-6.png similarity index 100% rename from yellow-paper/docs/l1-smart-contracts/images/com-abs-6.png rename to docs/static/img/protocol-specs/l1-smart-contracts/com-abs-6.png diff --git a/yellow-paper/docs/l1-smart-contracts/images/frontier/image-1.png b/docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-1.png similarity index 100% rename from yellow-paper/docs/l1-smart-contracts/images/frontier/image-1.png rename to docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-1.png diff --git a/yellow-paper/docs/l1-smart-contracts/images/frontier/image-2.png b/docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-2.png similarity index 100% rename from yellow-paper/docs/l1-smart-contracts/images/frontier/image-2.png rename to docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-2.png diff --git a/yellow-paper/docs/l1-smart-contracts/images/frontier/image-3.png b/docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-3.png similarity index 100% rename from yellow-paper/docs/l1-smart-contracts/images/frontier/image-3.png rename to docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-3.png diff --git a/yellow-paper/docs/l1-smart-contracts/images/frontier/image-4.png b/docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-4.png similarity index 100% rename from yellow-paper/docs/l1-smart-contracts/images/frontier/image-4.png rename to docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-4.png diff --git a/yellow-paper/docs/l1-smart-contracts/images/frontier/image-5.png b/docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-5.png similarity index 100% rename from yellow-paper/docs/l1-smart-contracts/images/frontier/image-5.png rename to docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-5.png diff --git a/yellow-paper/docs/l1-smart-contracts/images/frontier/image-6.png b/docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-6.png similarity index 100% rename from yellow-paper/docs/l1-smart-contracts/images/frontier/image-6.png rename to docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-6.png diff --git a/yellow-paper/docs/l1-smart-contracts/images/frontier/image-7.png b/docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-7.png similarity index 100% rename from yellow-paper/docs/l1-smart-contracts/images/frontier/image-7.png rename to docs/static/img/protocol-specs/l1-smart-contracts/frontier/image-7.png diff --git a/yellow-paper/docs/l1-smart-contracts/images/tree-order.png b/docs/static/img/protocol-specs/l1-smart-contracts/tree-order.png similarity index 100% rename from yellow-paper/docs/l1-smart-contracts/images/tree-order.png rename to docs/static/img/protocol-specs/l1-smart-contracts/tree-order.png diff --git a/yellow-paper/docs/public-vm/images/alu.png b/docs/static/img/protocol-specs/public-vm/alu.png similarity index 100% rename from yellow-paper/docs/public-vm/images/alu.png rename to docs/static/img/protocol-specs/public-vm/alu.png diff --git a/yellow-paper/docs/public-vm/images/avm-control-flow.png b/docs/static/img/protocol-specs/public-vm/avm-control-flow.png similarity index 100% rename from yellow-paper/docs/public-vm/images/avm-control-flow.png rename to docs/static/img/protocol-specs/public-vm/avm-control-flow.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/ADD.png b/docs/static/img/protocol-specs/public-vm/bit-formats/ADD.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/ADD.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/ADD.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/ADDRESS.png b/docs/static/img/protocol-specs/public-vm/bit-formats/ADDRESS.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/ADDRESS.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/ADDRESS.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/AND.png b/docs/static/img/protocol-specs/public-vm/bit-formats/AND.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/AND.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/AND.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKDAGASLIMIT.png b/docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKDAGASLIMIT.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKDAGASLIMIT.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKDAGASLIMIT.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKHEADERBYNUM.png b/docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKHEADERBYNUM.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKHEADERBYNUM.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKHEADERBYNUM.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKL1GASLIMIT.png b/docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKL1GASLIMIT.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKL1GASLIMIT.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKL1GASLIMIT.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKL2GASLIMIT.png b/docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKL2GASLIMIT.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKL2GASLIMIT.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKL2GASLIMIT.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKNUMBER.png b/docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKNUMBER.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKNUMBER.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/BLOCKNUMBER.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CALL.png b/docs/static/img/protocol-specs/public-vm/bit-formats/CALL.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/CALL.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/CALL.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CALLDATACOPY.png b/docs/static/img/protocol-specs/public-vm/bit-formats/CALLDATACOPY.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/CALLDATACOPY.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/CALLDATACOPY.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CAST.png b/docs/static/img/protocol-specs/public-vm/bit-formats/CAST.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/CAST.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/CAST.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CHAINID.png b/docs/static/img/protocol-specs/public-vm/bit-formats/CHAINID.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/CHAINID.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/CHAINID.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CMOV.png b/docs/static/img/protocol-specs/public-vm/bit-formats/CMOV.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/CMOV.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/CMOV.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/COINBASE.png b/docs/static/img/protocol-specs/public-vm/bit-formats/COINBASE.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/COINBASE.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/COINBASE.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CONTRACTCALLDEPTH.png b/docs/static/img/protocol-specs/public-vm/bit-formats/CONTRACTCALLDEPTH.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/CONTRACTCALLDEPTH.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/CONTRACTCALLDEPTH.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/DAGASLEFT.png b/docs/static/img/protocol-specs/public-vm/bit-formats/DAGASLEFT.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/DAGASLEFT.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/DAGASLEFT.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/DIV.png b/docs/static/img/protocol-specs/public-vm/bit-formats/DIV.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/DIV.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/DIV.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/EMITNOTEHASH.png b/docs/static/img/protocol-specs/public-vm/bit-formats/EMITNOTEHASH.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/EMITNOTEHASH.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/EMITNOTEHASH.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/EMITNULLIFIER.png b/docs/static/img/protocol-specs/public-vm/bit-formats/EMITNULLIFIER.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/EMITNULLIFIER.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/EMITNULLIFIER.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/EMITUNENCRYPTEDLOG.png b/docs/static/img/protocol-specs/public-vm/bit-formats/EMITUNENCRYPTEDLOG.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/EMITUNENCRYPTEDLOG.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/EMITUNENCRYPTEDLOG.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/EQ.png b/docs/static/img/protocol-specs/public-vm/bit-formats/EQ.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/EQ.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/EQ.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERDAGAS.png b/docs/static/img/protocol-specs/public-vm/bit-formats/FEEPERDAGAS.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERDAGAS.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/FEEPERDAGAS.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL1GAS.png b/docs/static/img/protocol-specs/public-vm/bit-formats/FEEPERL1GAS.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL1GAS.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/FEEPERL1GAS.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL2GAS.png b/docs/static/img/protocol-specs/public-vm/bit-formats/FEEPERL2GAS.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL2GAS.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/FEEPERL2GAS.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/INTERNALCALLDEPTH.png b/docs/static/img/protocol-specs/public-vm/bit-formats/INTERNALCALLDEPTH.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/INTERNALCALLDEPTH.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/INTERNALCALLDEPTH.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/INTERNALRETURN.png b/docs/static/img/protocol-specs/public-vm/bit-formats/INTERNALRETURN.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/INTERNALRETURN.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/INTERNALRETURN.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/JUMP.png b/docs/static/img/protocol-specs/public-vm/bit-formats/JUMP.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/JUMP.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/JUMP.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/JUMPI.png b/docs/static/img/protocol-specs/public-vm/bit-formats/JUMPI.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/JUMPI.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/JUMPI.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/L1GASLEFT.png b/docs/static/img/protocol-specs/public-vm/bit-formats/L1GASLEFT.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/L1GASLEFT.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/L1GASLEFT.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/L2GASLEFT.png b/docs/static/img/protocol-specs/public-vm/bit-formats/L2GASLEFT.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/L2GASLEFT.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/L2GASLEFT.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/LT.png b/docs/static/img/protocol-specs/public-vm/bit-formats/LT.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/LT.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/LT.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/LTE.png b/docs/static/img/protocol-specs/public-vm/bit-formats/LTE.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/LTE.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/LTE.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/MOV.png b/docs/static/img/protocol-specs/public-vm/bit-formats/MOV.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/MOV.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/MOV.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/MUL.png b/docs/static/img/protocol-specs/public-vm/bit-formats/MUL.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/MUL.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/MUL.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/NOT.png b/docs/static/img/protocol-specs/public-vm/bit-formats/NOT.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/NOT.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/NOT.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/OR.png b/docs/static/img/protocol-specs/public-vm/bit-formats/OR.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/OR.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/OR.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/ORIGIN.png b/docs/static/img/protocol-specs/public-vm/bit-formats/ORIGIN.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/ORIGIN.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/ORIGIN.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/PORTAL.png b/docs/static/img/protocol-specs/public-vm/bit-formats/PORTAL.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/PORTAL.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/PORTAL.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/READL1TOL2MSG.png b/docs/static/img/protocol-specs/public-vm/bit-formats/READL1TOL2MSG.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/READL1TOL2MSG.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/READL1TOL2MSG.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/RETURN.png b/docs/static/img/protocol-specs/public-vm/bit-formats/RETURN.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/RETURN.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/RETURN.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/REVERT.png b/docs/static/img/protocol-specs/public-vm/bit-formats/REVERT.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/REVERT.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/REVERT.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SENDER.png b/docs/static/img/protocol-specs/public-vm/bit-formats/SENDER.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/SENDER.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/SENDER.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SENDL2TOL1MSG.png b/docs/static/img/protocol-specs/public-vm/bit-formats/SENDL2TOL1MSG.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/SENDL2TOL1MSG.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/SENDL2TOL1MSG.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SET.png b/docs/static/img/protocol-specs/public-vm/bit-formats/SET.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/SET.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/SET.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SHL.png b/docs/static/img/protocol-specs/public-vm/bit-formats/SHL.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/SHL.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/SHL.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SHR.png b/docs/static/img/protocol-specs/public-vm/bit-formats/SHR.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/SHR.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/SHR.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SLOAD.png b/docs/static/img/protocol-specs/public-vm/bit-formats/SLOAD.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/SLOAD.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/SLOAD.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SSTORE.png b/docs/static/img/protocol-specs/public-vm/bit-formats/SSTORE.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/SSTORE.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/SSTORE.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/STATICCALL.png b/docs/static/img/protocol-specs/public-vm/bit-formats/STATICCALL.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/STATICCALL.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/STATICCALL.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/STORAGEADDRESS.png b/docs/static/img/protocol-specs/public-vm/bit-formats/STORAGEADDRESS.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/STORAGEADDRESS.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/STORAGEADDRESS.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SUB.png b/docs/static/img/protocol-specs/public-vm/bit-formats/SUB.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/SUB.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/SUB.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/TIMESTAMP.png b/docs/static/img/protocol-specs/public-vm/bit-formats/TIMESTAMP.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/TIMESTAMP.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/TIMESTAMP.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/VERSION.png b/docs/static/img/protocol-specs/public-vm/bit-formats/VERSION.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/VERSION.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/VERSION.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/XOR.png b/docs/static/img/protocol-specs/public-vm/bit-formats/XOR.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/XOR.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/XOR.png diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/internalcall.png b/docs/static/img/protocol-specs/public-vm/bit-formats/internalcall.png similarity index 100% rename from yellow-paper/docs/public-vm/gen/images/bit-formats/internalcall.png rename to docs/static/img/protocol-specs/public-vm/bit-formats/internalcall.png diff --git a/yellow-paper/docs/public-vm/images/memory.png b/docs/static/img/protocol-specs/public-vm/memory.png similarity index 100% rename from yellow-paper/docs/public-vm/images/memory.png rename to docs/static/img/protocol-specs/public-vm/memory.png diff --git a/docs/yarn.lock b/docs/yarn.lock index be4e6d0886b7..33eee5c977f9 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3870,7 +3870,7 @@ debug@2.6.9, debug@^2.6.0: dependencies: ms "2.0.0" -debug@4, debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: +debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -5775,6 +5775,17 @@ mdast-util-definitions@^4.0.0: dependencies: unist-util-visit "^2.0.0" +mdast-util-from-markdown@^0.8.0: + version "0.8.5" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c" + integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-to-string "^2.0.0" + micromark "~2.11.0" + parse-entities "^2.0.0" + unist-util-stringify-position "^2.0.0" + mdast-util-to-hast@10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" @@ -5789,6 +5800,20 @@ mdast-util-to-hast@10.0.1: unist-util-position "^3.0.0" unist-util-visit "^2.0.0" +mdast-util-to-hast@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz#61875526a017d8857b71abc9333942700b2d3604" + integrity sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + mdast-util-definitions "^4.0.0" + mdurl "^1.0.0" + unist-builder "^2.0.0" + unist-util-generated "^1.0.0" + unist-util-position "^3.0.0" + unist-util-visit "^2.0.0" + mdast-util-to-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" @@ -5863,6 +5888,14 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micromark@~2.11.0: + version "2.11.4" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a" + integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== + dependencies: + debug "^4.0.0" + parse-entities "^2.0.0" + micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -6961,6 +6994,11 @@ react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.0: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + "react-is@^17.0.1 || ^18.0.0": version "18.2.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" @@ -6988,6 +7026,24 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1: dependencies: "@babel/runtime" "^7.10.3" +react-markdown@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-6.0.0.tgz#e63cd32d095e864384d524986c44c34c919de517" + integrity sha512-MC+zljUJeoLb4RbDm/wRbfoQFEZGz4TDOt/wb4dEehdaJWxLMn/T2IgwhQy0VYhuPEd2fhd7iOayE8lmENU0FA== + dependencies: + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.3" + comma-separated-tokens "^1.0.0" + prop-types "^15.7.2" + property-information "^5.0.0" + react-is "^17.0.0" + remark-parse "^9.0.0" + remark-rehype "^8.0.0" + space-separated-tokens "^1.1.0" + style-to-object "^0.3.0" + unified "^9.0.0" + unist-util-visit "^2.0.0" + react-player@^2.12.0: version "2.14.1" resolved "https://registry.yarnpkg.com/react-player/-/react-player-2.14.1.tgz#fc434c0e1e6161e76f5d5970721596c4acec52b1" @@ -7246,6 +7302,20 @@ remark-parse@8.0.3: vfile-location "^3.0.0" xtend "^4.0.1" +remark-parse@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" + integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== + dependencies: + mdast-util-from-markdown "^0.8.0" + +remark-rehype@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-8.1.0.tgz#610509a043484c1e697437fa5eb3fd992617c945" + integrity sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA== + dependencies: + mdast-util-to-hast "^10.2.0" + remark-squeeze-paragraphs@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" @@ -7745,7 +7815,7 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -space-separated-tokens@^1.0.0: +space-separated-tokens@^1.0.0, space-separated-tokens@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== diff --git a/iac/mainnet-fork/scripts/wait_for_fork b/iac/mainnet-fork/scripts/wait_for_fork index 831e06723e26..7bd317fd28b6 100755 --- a/iac/mainnet-fork/scripts/wait_for_fork +++ b/iac/mainnet-fork/scripts/wait_for_fork @@ -6,7 +6,7 @@ set -e # This script waits on a healthy status from the fork - a valid response to the chainid request # We retry every 20 seconds, and wait for a total of 5 minutes (15 times) -export ETHEREUM_HOST="https://aztec-mainnet-fork.aztec.network:8545/$API_KEY" +export ETHEREUM_HOST="https://$DEPLOY_TAG-mainnet-fork.aztec.network:8545/$FORK_API_KEY" curl -H "Content-Type: application/json" -X POST --data '{"method":"eth_chainId","params":[],"id":33,"jsonrpc":"2.0"}' \ --connect-timeout 30 \ diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index ecc56722a511..6661fc67443d 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -26,6 +26,8 @@ library Constants { uint256 internal constant MAX_NULLIFIER_READ_REQUESTS_PER_CALL = 2; uint256 internal constant MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL = 2; uint256 internal constant MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; + uint256 internal constant MAX_ENCRYPTED_LOGS_PER_CALL = 4; + uint256 internal constant MAX_UNENCRYPTED_LOGS_PER_CALL = 4; uint256 internal constant MAX_NEW_NOTE_HASHES_PER_TX = 64; uint256 internal constant MAX_NEW_NULLIFIERS_PER_TX = 64; uint256 internal constant MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX = 8; @@ -37,8 +39,11 @@ library Constants { uint256 internal constant MAX_NULLIFIER_READ_REQUESTS_PER_TX = 8; uint256 internal constant MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX = 8; uint256 internal constant MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX = 4; + uint256 internal constant MAX_ENCRYPTED_LOGS_PER_TX = 8; + uint256 internal constant MAX_UNENCRYPTED_LOGS_PER_TX = 8; uint256 internal constant NUM_ENCRYPTED_LOGS_HASHES_PER_TX = 1; uint256 internal constant NUM_UNENCRYPTED_LOGS_HASHES_PER_TX = 1; + uint256 internal constant MAX_PUBLIC_DATA_HINTS = 64; uint256 internal constant NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP = 16; uint256 internal constant VK_TREE_HEIGHT = 3; uint256 internal constant FUNCTION_TREE_HEIGHT = 5; @@ -65,11 +70,12 @@ library Constants { uint256 internal constant FUNCTION_SELECTOR_NUM_BYTES = 4; uint256 internal constant ARGS_HASH_CHUNK_LENGTH = 64; uint256 internal constant ARGS_HASH_CHUNK_COUNT = 64; + uint256 internal constant MAX_ARGS_LENGTH = ARGS_HASH_CHUNK_COUNT * ARGS_HASH_CHUNK_LENGTH; uint256 internal constant INITIALIZATION_SLOT_SEPARATOR = 1000_000_000; uint256 internal constant INITIAL_L2_BLOCK_NUM = 1; - uint256 internal constant BLOB_SIZE_IN_BYTES = 126976; + uint256 internal constant BLOB_SIZE_IN_BYTES = 31 * 4096; uint256 internal constant NESTED_CALL_L2_GAS_BUFFER = 20000; - uint256 internal constant MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 16000; + uint256 internal constant MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 16200; uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 3000; uint256 internal constant MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 3000; uint256 internal constant REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 19; @@ -83,18 +89,13 @@ library Constants { uint256 internal constant DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE = 0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631; uint256 internal constant DEPLOYER_CONTRACT_ADDRESS = - 0x1df42e0457430b8d294d920181cc72ae0e3c5f8afd8d62d461bd26773cfdf3c1; - uint256 internal constant L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH = 17; - uint256 internal constant MAX_NOTE_FIELDS_LENGTH = 20; - uint256 internal constant GET_NOTE_ORACLE_RETURN_LENGTH = 23; - uint256 internal constant MAX_NOTES_PER_PAGE = 10; - uint256 internal constant VIEW_NOTE_ORACLE_RETURN_LENGTH = 212; + 0x1b5ecf3d26907648cf737f4304759b8c5850478e839e72f8ce1f5791b286e8f2; uint256 internal constant AZTEC_ADDRESS_LENGTH = 1; - uint256 internal constant CALL_CONTEXT_LENGTH = 18; - uint256 internal constant GAS_SETTINGS_LENGTH = 10; uint256 internal constant DIMENSION_GAS_SETTINGS_LENGTH = 3; uint256 internal constant GAS_FEES_LENGTH = 3; - uint256 internal constant GAS_USED_LENGTH = 3; + uint256 internal constant GAS_LENGTH = 3; + uint256 internal constant GAS_SETTINGS_LENGTH = 1 + 3 * DIMENSION_GAS_SETTINGS_LENGTH; + uint256 internal constant CALL_CONTEXT_LENGTH = 8 + GAS_SETTINGS_LENGTH + GAS_LENGTH; uint256 internal constant CONTENT_COMMITMENT_LENGTH = 4; uint256 internal constant CONTRACT_INSTANCE_LENGTH = 6; uint256 internal constant CONTRACT_STORAGE_READ_LENGTH = 2; @@ -102,21 +103,48 @@ library Constants { uint256 internal constant ETH_ADDRESS_LENGTH = 1; uint256 internal constant FUNCTION_DATA_LENGTH = 2; uint256 internal constant FUNCTION_LEAF_PREIMAGE_LENGTH = 5; - uint256 internal constant GLOBAL_VARIABLES_LENGTH = 9; - uint256 internal constant HEADER_LENGTH = 23; + uint256 internal constant GLOBAL_VARIABLES_LENGTH = 6 + GAS_FEES_LENGTH; + uint256 internal constant APPEND_ONLY_TREE_SNAPSHOT_LENGTH = 2; uint256 internal constant L1_TO_L2_MESSAGE_LENGTH = 6; uint256 internal constant L2_TO_L1_MESSAGE_LENGTH = 2; uint256 internal constant MAX_BLOCK_NUMBER_LENGTH = 2; uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH = 4; uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_CONTEXT_LENGTH = 5; uint256 internal constant PARTIAL_STATE_REFERENCE_LENGTH = 6; - uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 221; - uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 218; - uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 209; - uint256 internal constant STATE_REFERENCE_LENGTH = 8; + uint256 internal constant READ_REQUEST_LENGTH = 2; + uint256 internal constant SIDE_EFFECT_LENGTH = 2; + uint256 internal constant SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH = 3; + uint256 internal constant STATE_REFERENCE_LENGTH = + APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; uint256 internal constant TX_CONTEXT_DATA_LENGTH = 4; - uint256 internal constant TX_REQUEST_LENGTH = 8; - uint256 internal constant ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH = 22; + uint256 internal constant TX_REQUEST_LENGTH = + 2 + TX_CONTEXT_DATA_LENGTH + FUNCTION_DATA_LENGTH + GAS_SETTINGS_LENGTH; + uint256 internal constant HEADER_LENGTH = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + + CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH; + uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = CALL_CONTEXT_LENGTH + 3 + + MAX_BLOCK_NUMBER_LENGTH + (SIDE_EFFECT_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + + (NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH * MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL) + + (SIDE_EFFECT_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL) + + (SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + + (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2 + + (SIDE_EFFECT_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL) + + (SIDE_EFFECT_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + 2 + HEADER_LENGTH + 2; + uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = CALL_CONTEXT_LENGTH + 2 + + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + + (READ_REQUEST_LENGTH * MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL) + + (CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL) + + (CONTRACT_STORAGE_READ_LENGTH * MAX_PUBLIC_DATA_READS_PER_CALL) + + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + (SIDE_EFFECT_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL) + + (SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + + (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2 + + (SIDE_EFFECT_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + 1 + HEADER_LENGTH + AZTEC_ADDRESS_LENGTH /* revert_code */ + + 1 + GAS_LENGTH; + uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = + AZTEC_ADDRESS_LENGTH + FUNCTION_DATA_LENGTH + PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH; + uint256 internal constant ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH = + 2 + FUNCTION_DATA_LENGTH + CALL_CONTEXT_LENGTH; uint256 internal constant GET_NOTES_ORACLE_RETURN_LENGTH = 674; uint256 internal constant NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 2048; uint256 internal constant NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048; diff --git a/l1-contracts/src/core/libraries/HeaderLib.sol b/l1-contracts/src/core/libraries/HeaderLib.sol index 24eb199e0b5a..db04f207f17d 100644 --- a/l1-contracts/src/core/libraries/HeaderLib.sol +++ b/l1-contracts/src/core/libraries/HeaderLib.sol @@ -70,7 +70,7 @@ library HeaderLib { struct StateReference { AppendOnlyTreeSnapshot l1ToL2MessageTree; - // Note: Can't use "partial" name here as in yellow paper because it is a reserved solidity keyword + // Note: Can't use "partial" name here as in protocol specs because it is a reserved solidity keyword PartialStateReference partialStateReference; } diff --git a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol index a57d4a26a25e..c3f95e61170e 100644 --- a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol +++ b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol @@ -239,17 +239,21 @@ library TxsDecoder { uint256 privateCircuitPublicInputLogsLength = read4(_body, offset); offset += 0x4; - // Hash the logs of this iteration's function call - bytes32 privateCircuitPublicInputsLogsHash = - Hash.sha256ToField(slice(_body, offset, privateCircuitPublicInputLogsLength)); - offset += privateCircuitPublicInputLogsLength; - // Decrease remaining logs length by this privateCircuitPublicInputsLogs's length (len(I?_LOGS)) and 4 bytes for I?_LOGS_LEN remainingLogsLength -= (privateCircuitPublicInputLogsLength + 0x4); - kernelPublicInputsLogsHash = Hash.sha256ToField( - bytes.concat(kernelPublicInputsLogsHash, privateCircuitPublicInputsLogsHash) - ); + while (privateCircuitPublicInputLogsLength > 0) { + uint256 singleCallLogsLength = read4(_body, offset); + offset += 0x4; + + bytes32 singleLogHash = Hash.sha256ToField(slice(_body, offset, singleCallLogsLength)); + offset += singleCallLogsLength; + + kernelPublicInputsLogsHash = + Hash.sha256ToField(bytes.concat(kernelPublicInputsLogsHash, singleLogHash)); + + privateCircuitPublicInputLogsLength -= (singleCallLogsLength + 0x4); + } } return (kernelPublicInputsLogsHash, offset); diff --git a/l1-contracts/test/decoders/Decoders.t.sol b/l1-contracts/test/decoders/Decoders.t.sol index 3857a9305d09..accec36ab519 100644 --- a/l1-contracts/test/decoders/Decoders.t.sol +++ b/l1-contracts/test/decoders/Decoders.t.sol @@ -180,25 +180,20 @@ contract DecodersTest is DecoderBase { (bytes32 logsHash, uint256 bytesAdvanced) = txsHelper.computeKernelLogsHash(encodedLogs); - bytes32 kernelPublicInputsLogsHash = bytes32(0); - bytes32 privateCircuitPublicInputsLogsHash = Hash.sha256ToField(new bytes(0)); - - bytes32 referenceLogsHash = Hash.sha256ToField( - abi.encodePacked(kernelPublicInputsLogsHash, privateCircuitPublicInputsLogsHash) - ); - assertEq(bytesAdvanced, encodedLogs.length, "Advanced by an incorrect number of bytes"); - assertEq(logsHash, referenceLogsHash, "Incorrect logs hash"); + assertEq(logsHash, bytes32(0), "Incorrect logs hash"); } function testComputeKernelLogs1Iteration() public { // || K_LOGS_LEN | I1_LOGS_LEN | I1_LOGS || // K_LOGS_LEN = 4 + 8 = 12 (hex"0000000c") // I1_LOGS_LEN = 8 (hex"00000008") - // I1_LOGS = 8 bytes (hex"0000000493e78a70") // Note: 00000004 is the length of 1 log within function logs - bytes memory firstFunctionCallLogs = hex"0000000493e78a70"; + // I1_LOGS = 8 bytes (hex"0000000493e78a70") + bytes memory firstFunctionCallLogs = hex"93e78a70"; // Prefix logs with length of kernel logs (12) and length of iteration 1 logs (8) - bytes memory encodedLogs = abi.encodePacked(hex"0000000c00000008", firstFunctionCallLogs); + // Note: 00000004 is the length of 1 log within function logs + bytes memory encodedLogs = + abi.encodePacked(hex"0000000c00000008", hex"00000004", firstFunctionCallLogs); (bytes32 logsHash, uint256 bytesAdvanced) = txsHelper.computeKernelLogsHash(encodedLogs); // Zero because this is the first iteration @@ -222,10 +217,15 @@ contract DecodersTest is DecoderBase { // I1_LOGS = 8 random bytes (hex"0000000493e78a70") // I2_LOGS_LEN = 20 (hex"00000014") // I2_LOGS = 20 bytes (hex"0000001006a86173c86c6d3f108eefc36e7fb014") - bytes memory firstFunctionCallLogs = hex"0000000493e78a70"; - bytes memory secondFunctionCallLogs = hex"0000001006a86173c86c6d3f108eefc36e7fb014"; + bytes memory firstFunctionCallLogs = hex"93e78a70"; + bytes memory secondFunctionCallLogs = hex"06a86173c86c6d3f108eefc36e7fb014"; bytes memory encodedLogs = abi.encodePacked( - hex"0000002400000008", firstFunctionCallLogs, hex"00000014", secondFunctionCallLogs + hex"0000002400000008", + hex"00000004", + firstFunctionCallLogs, + hex"00000014", + hex"00000010", + secondFunctionCallLogs ); (bytes32 logsHash, uint256 bytesAdvanced) = txsHelper.computeKernelLogsHash(encodedLogs); @@ -254,15 +254,17 @@ contract DecodersTest is DecoderBase { // I2_LOGS = 0 bytes (hex"") // I3_LOGS_LEN = 20 (hex"00000014") // I3_LOGS = 20 random bytes (hex"0000001006a86173c86c6d3f108eefc36e7fb014") - bytes memory firstFunctionCallLogs = hex"0000000493e78a70"; + bytes memory firstFunctionCallLogs = hex"93e78a70"; bytes memory secondFunctionCallLogs = hex""; - bytes memory thirdFunctionCallLogs = hex"0000001006a86173c86c6d3f108eefc36e7fb014"; + bytes memory thirdFunctionCallLogs = hex"06a86173c86c6d3f108eefc36e7fb014"; bytes memory encodedLogs = abi.encodePacked( hex"0000002800000008", + hex"00000004", firstFunctionCallLogs, hex"00000000", secondFunctionCallLogs, hex"00000014", + hex"00000010", thirdFunctionCallLogs ); (bytes32 logsHash, uint256 bytesAdvanced) = txsHelper.computeKernelLogsHash(encodedLogs); @@ -270,19 +272,13 @@ contract DecodersTest is DecoderBase { bytes32 referenceLogsHashFromIteration1 = Hash.sha256ToField(abi.encodePacked(bytes32(0), Hash.sha256ToField(firstFunctionCallLogs))); - bytes32 privateCircuitPublicInputsLogsHashSecondCall = - Hash.sha256ToField(secondFunctionCallLogs); - - bytes32 referenceLogsHashFromIteration2 = Hash.sha256ToField( - abi.encodePacked( - referenceLogsHashFromIteration1, privateCircuitPublicInputsLogsHashSecondCall - ) - ); + // Note: as of resolving #5017, we now hash logs inside the circuits + // Following the YP, we skip any zero length logs, hence no use of secondFunctionCallLogs here bytes32 privateCircuitPublicInputsLogsHashThirdCall = Hash.sha256ToField(thirdFunctionCallLogs); bytes32 referenceLogsHashFromIteration3 = Hash.sha256ToField( - abi.encodePacked(referenceLogsHashFromIteration2, privateCircuitPublicInputsLogsHashThirdCall) + abi.encodePacked(referenceLogsHashFromIteration1, privateCircuitPublicInputsLogsHashThirdCall) ); assertEq(bytesAdvanced, encodedLogs.length, "Advanced by an incorrect number of bytes"); diff --git a/l1-contracts/test/fixtures/empty_block_0.json b/l1-contracts/test/fixtures/empty_block_0.json index fc35e30bee67..16e7729fc677 100644 --- a/l1-contracts/test/fixtures/empty_block_0.json +++ b/l1-contracts/test/fixtures/empty_block_0.json @@ -8,7 +8,7 @@ "l2ToL1Messages": [] }, "block": { - "archive": "0x2ea0c3d3ffef649532de4fb75c9135681ef65b926876b5ff37a4bacfb679f558", + "archive": "0x2683d379c0ad62e225372f35b74366d8c3cd145a12dbbb2028456da89f889be1", "body": "0x00000000", "txsEffectsHash": "0x00df6b1c97b9e01113fa0363d9ff71c85addc74e92b22d433b2fb082d2493896", "decodedHeader": { @@ -23,8 +23,8 @@ "chainId": 31337, "timestamp": 0, "version": 1, - "coinbase": "0xf6a7844f33ced45fbfeaa9ba463a706b30d4c454", - "feeRecipient": "0x115f6d9664fe6497dec1741573007fcd96fc24124e05b2d415fe4e43e0de4d6e", + "coinbase": "0xd70b960abd35f82aac6df2d1ca6617b5bcd95ba5", + "feeRecipient": "0x0c67b9f94de6beccefc03b63ba448b53464348836ef20b3e6183c5d4f85653ee", "gasFees": { "feePerDaGas": 0, "feePerL1Gas": 0, @@ -56,8 +56,8 @@ } } }, - "header": "0x05b0b6df52f1d47d0406318558052c89a174fbc9d615def82b3cc9ccc1937db800000001000000000000000000000000000000000000000000000000000000000000000100df6b1c97b9e01113fa0363d9ff71c85addc74e92b22d433b2fb082d249389600089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000001016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000800bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000f6a7844f33ced45fbfeaa9ba463a706b30d4c454115f6d9664fe6497dec1741573007fcd96fc24124e05b2d415fe4e43e0de4d6e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "publicInputsHash": "0x000150a504a83df5a4a24f26081fb7397809f2ef5976b687fbdeefb5d42da7f3", + "header": "0x05b0b6df52f1d47d0406318558052c89a174fbc9d615def82b3cc9ccc1937db800000001000000000000000000000000000000000000000000000000000000000000000100df6b1c97b9e01113fa0363d9ff71c85addc74e92b22d433b2fb082d249389600089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000001016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000800bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000d70b960abd35f82aac6df2d1ca6617b5bcd95ba50c67b9f94de6beccefc03b63ba448b53464348836ef20b3e6183c5d4f85653ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "publicInputsHash": "0x00ee6ce1f8afb6a9d9da7165bbff8d03d3f2e4ae6a65a9265ecbb7c600244a9c", "numTxs": 0 } } \ No newline at end of file diff --git a/l1-contracts/test/fixtures/empty_block_1.json b/l1-contracts/test/fixtures/empty_block_1.json index 11c88bc30d02..6eb046a80359 100644 --- a/l1-contracts/test/fixtures/empty_block_1.json +++ b/l1-contracts/test/fixtures/empty_block_1.json @@ -8,7 +8,7 @@ "l2ToL1Messages": [] }, "block": { - "archive": "0x20411bada543bf4a76e1e2b96c15059c7c81b81b4dec36b15102bcc72dfdebff", + "archive": "0x0be67a10fc9ab9372e7fdfa4fcce95a3ed24d42fb6694ffcd3d418d504d8fef4", "body": "0x00000000", "txsEffectsHash": "0x00df6b1c97b9e01113fa0363d9ff71c85addc74e92b22d433b2fb082d2493896", "decodedHeader": { @@ -21,10 +21,10 @@ "globalVariables": { "blockNumber": 2, "chainId": 31337, - "timestamp": 1712782698, + "timestamp": 1712912168, "version": 1, - "coinbase": "0xf6a7844f33ced45fbfeaa9ba463a706b30d4c454", - "feeRecipient": "0x115f6d9664fe6497dec1741573007fcd96fc24124e05b2d415fe4e43e0de4d6e", + "coinbase": "0xd70b960abd35f82aac6df2d1ca6617b5bcd95ba5", + "feeRecipient": "0x0c67b9f94de6beccefc03b63ba448b53464348836ef20b3e6183c5d4f85653ee", "gasFees": { "feePerDaGas": 0, "feePerL1Gas": 0, @@ -33,7 +33,7 @@ }, "lastArchive": { "nextAvailableLeafIndex": 2, - "root": "0x2ea0c3d3ffef649532de4fb75c9135681ef65b926876b5ff37a4bacfb679f558" + "root": "0x2683d379c0ad62e225372f35b74366d8c3cd145a12dbbb2028456da89f889be1" }, "stateReference": { "l1ToL2MessageTree": { @@ -56,8 +56,8 @@ } } }, - "header": "0x2ea0c3d3ffef649532de4fb75c9135681ef65b926876b5ff37a4bacfb679f55800000002000000000000000000000000000000000000000000000000000000000000000100df6b1c97b9e01113fa0363d9ff71c85addc74e92b22d433b2fb082d249389600089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000002016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000001000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000c00000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000006616fd6af6a7844f33ced45fbfeaa9ba463a706b30d4c454115f6d9664fe6497dec1741573007fcd96fc24124e05b2d415fe4e43e0de4d6e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "publicInputsHash": "0x00da6d809b78297d6f97202d0679da5a45cfbc2c6594eaeb3f0ac4deba7c6b2e", + "header": "0x2683d379c0ad62e225372f35b74366d8c3cd145a12dbbb2028456da89f889be100000002000000000000000000000000000000000000000000000000000000000000000100df6b1c97b9e01113fa0363d9ff71c85addc74e92b22d433b2fb082d249389600089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000002016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000001000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000c00000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000006618f728d70b960abd35f82aac6df2d1ca6617b5bcd95ba50c67b9f94de6beccefc03b63ba448b53464348836ef20b3e6183c5d4f85653ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "publicInputsHash": "0x00bb8af4db44612602143f2507b6f07f4dc5fdede045494a1467c4bea354bcae", "numTxs": 0 } } \ No newline at end of file diff --git a/l1-contracts/test/fixtures/mixed_block_0.json b/l1-contracts/test/fixtures/mixed_block_0.json index eeb338cc7ec0..ad43a849a541 100644 --- a/l1-contracts/test/fixtures/mixed_block_0.json +++ b/l1-contracts/test/fixtures/mixed_block_0.json @@ -34,7 +34,7 @@ ] }, "block": { - "archive": "0x198e7398bee770978f22a61c05397f4a663b8a1068051fac5173236bfbc3c853", + "archive": "0x195de7b601a7882443a8b98043c504ef921f11a94dfa17ce1f5bc4461c685877", "body": "0x0000000400400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000014100000000000000000000000000000000000000000000000000000000000001420000000000000000000000000000000000000000000000000000000000000143000000000000000000000000000000000000000000000000000000000000014400000000000000000000000000000000000000000000000000000000000001450000000000000000000000000000000000000000000000000000000000000146000000000000000000000000000000000000000000000000000000000000014700000000000000000000000000000000000000000000000000000000000001480000000000000000000000000000000000000000000000000000000000000149000000000000000000000000000000000000000000000000000000000000014a000000000000000000000000000000000000000000000000000000000000014b000000000000000000000000000000000000000000000000000000000000014c000000000000000000000000000000000000000000000000000000000000014d000000000000000000000000000000000000000000000000000000000000014e000000000000000000000000000000000000000000000000000000000000014f0000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000015100000000000000000000000000000000000000000000000000000000000001520000000000000000000000000000000000000000000000000000000000000153000000000000000000000000000000000000000000000000000000000000015400000000000000000000000000000000000000000000000000000000000001550000000000000000000000000000000000000000000000000000000000000156000000000000000000000000000000000000000000000000000000000000015700000000000000000000000000000000000000000000000000000000000001580000000000000000000000000000000000000000000000000000000000000159000000000000000000000000000000000000000000000000000000000000015a000000000000000000000000000000000000000000000000000000000000015b000000000000000000000000000000000000000000000000000000000000015c000000000000000000000000000000000000000000000000000000000000015d000000000000000000000000000000000000000000000000000000000000015e000000000000000000000000000000000000000000000000000000000000015f0000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000001620000000000000000000000000000000000000000000000000000000000000163000000000000000000000000000000000000000000000000000000000000016400000000000000000000000000000000000000000000000000000000000001650000000000000000000000000000000000000000000000000000000000000166000000000000000000000000000000000000000000000000000000000000016700000000000000000000000000000000000000000000000000000000000001680000000000000000000000000000000000000000000000000000000000000169000000000000000000000000000000000000000000000000000000000000016a000000000000000000000000000000000000000000000000000000000000016b000000000000000000000000000000000000000000000000000000000000016c000000000000000000000000000000000000000000000000000000000000016d000000000000000000000000000000000000000000000000000000000000016e000000000000000000000000000000000000000000000000000000000000016f0000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000017100000000000000000000000000000000000000000000000000000000000001720000000000000000000000000000000000000000000000000000000000000173000000000000000000000000000000000000000000000000000000000000017400000000000000000000000000000000000000000000000000000000000001750000000000000000000000000000000000000000000000000000000000000176000000000000000000000000000000000000000000000000000000000000017700000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000179000000000000000000000000000000000000000000000000000000000000017a000000000000000000000000000000000000000000000000000000000000017b000000000000000000000000000000000000000000000000000000000000017c000000000000000000000000000000000000000000000000000000000000017d000000000000000000000000000000000000000000000000000000000000017e000000000000000000000000000000000000000000000000000000000000017f3f0000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000024100000000000000000000000000000000000000000000000000000000000002420000000000000000000000000000000000000000000000000000000000000243000000000000000000000000000000000000000000000000000000000000024400000000000000000000000000000000000000000000000000000000000002450000000000000000000000000000000000000000000000000000000000000246000000000000000000000000000000000000000000000000000000000000024700000000000000000000000000000000000000000000000000000000000002480000000000000000000000000000000000000000000000000000000000000249000000000000000000000000000000000000000000000000000000000000024a000000000000000000000000000000000000000000000000000000000000024b000000000000000000000000000000000000000000000000000000000000024c000000000000000000000000000000000000000000000000000000000000024d000000000000000000000000000000000000000000000000000000000000024e000000000000000000000000000000000000000000000000000000000000024f0000000000000000000000000000000000000000000000000000000000000250000000000000000000000000000000000000000000000000000000000000025100000000000000000000000000000000000000000000000000000000000002520000000000000000000000000000000000000000000000000000000000000253000000000000000000000000000000000000000000000000000000000000025400000000000000000000000000000000000000000000000000000000000002550000000000000000000000000000000000000000000000000000000000000256000000000000000000000000000000000000000000000000000000000000025700000000000000000000000000000000000000000000000000000000000002580000000000000000000000000000000000000000000000000000000000000259000000000000000000000000000000000000000000000000000000000000025a000000000000000000000000000000000000000000000000000000000000025b000000000000000000000000000000000000000000000000000000000000025c000000000000000000000000000000000000000000000000000000000000025d000000000000000000000000000000000000000000000000000000000000025e000000000000000000000000000000000000000000000000000000000000025f0000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000026100000000000000000000000000000000000000000000000000000000000002620000000000000000000000000000000000000000000000000000000000000263000000000000000000000000000000000000000000000000000000000000026400000000000000000000000000000000000000000000000000000000000002650000000000000000000000000000000000000000000000000000000000000266000000000000000000000000000000000000000000000000000000000000026700000000000000000000000000000000000000000000000000000000000002680000000000000000000000000000000000000000000000000000000000000269000000000000000000000000000000000000000000000000000000000000026a000000000000000000000000000000000000000000000000000000000000026b000000000000000000000000000000000000000000000000000000000000026c000000000000000000000000000000000000000000000000000000000000026d000000000000000000000000000000000000000000000000000000000000026e000000000000000000000000000000000000000000000000000000000000026f0000000000000000000000000000000000000000000000000000000000000270000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000002720000000000000000000000000000000000000000000000000000000000000273000000000000000000000000000000000000000000000000000000000000027400000000000000000000000000000000000000000000000000000000000002750000000000000000000000000000000000000000000000000000000000000276000000000000000000000000000000000000000000000000000000000000027700000000000000000000000000000000000000000000000000000000000002780000000000000000000000000000000000000000000000000000000000000279000000000000000000000000000000000000000000000000000000000000027a000000000000000000000000000000000000000000000000000000000000027b000000000000000000000000000000000000000000000000000000000000027c000000000000000000000000000000000000000000000000000000000000027d000000000000000000000000000000000000000000000000000000000000027e0200000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000341200000000000000000000000000000000000000000000000000000000000000540000000000000000000000000000000000000000000000000000000000000054a0000000000000000000000000000000000000000000000000000000000000541000000000000000000000000000000000000000000000000000000000000054b0000000000000000000000000000000000000000000000000000000000000542000000000000000000000000000000000000000000000000000000000000054c0000000000000000000000000000000000000000000000000000000000000543000000000000000000000000000000000000000000000000000000000000054d0000000000000000000000000000000000000000000000000000000000000544000000000000000000000000000000000000000000000000000000000000054e0000000000000000000000000000000000000000000000000000000000000545000000000000000000000000000000000000000000000000000000000000054f00000000000000000000000000000000000000000000000000000000000005460000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000054700000000000000000000000000000000000000000000000000000000000005510000000000000000000000000000000000000000000000000000000000000548000000000000000000000000000000000000000000000000000000000000055200000000000000000000000000000000000000000000000000000000000005490000000000000000000000000000000000000000000000000000000000000553000000000000000000000000000000000000000000000000000000000000054a0000000000000000000000000000000000000000000000000000000000000554000000000000000000000000000000000000000000000000000000000000054b0000000000000000000000000000000000000000000000000000000000000555000000000000000000000000000000000000000000000000000000000000054c0000000000000000000000000000000000000000000000000000000000000556000000000000000000000000000000000000000000000000000000000000054d0000000000000000000000000000000000000000000000000000000000000557000000000000000000000000000000000000000000000000000000000000054e0000000000000000000000000000000000000000000000000000000000000558000000000000000000000000000000000000000000000000000000000000054f00000000000000000000000000000000000000000000000000000000000005590000000000000000000000000000000000000000000000000000000000000550000000000000000000000000000000000000000000000000000000000000055a0000000000000000000000000000000000000000000000000000000000000551000000000000000000000000000000000000000000000000000000000000055b0000000000000000000000000000000000000000000000000000000000000552000000000000000000000000000000000000000000000000000000000000055c0000000000000000000000000000000000000000000000000000000000000553000000000000000000000000000000000000000000000000000000000000055d0000000000000000000000000000000000000000000000000000000000000554000000000000000000000000000000000000000000000000000000000000055e0000000000000000000000000000000000000000000000000000000000000555000000000000000000000000000000000000000000000000000000000000055f00000000000000000000000000000000000000000000000000000000000005560000000000000000000000000000000000000000000000000000000000000560000000000000000000000000000000000000000000000000000000000000055700000000000000000000000000000000000000000000000000000000000005610000000000000000000000000000000000000000000000000000000000000558000000000000000000000000000000000000000000000000000000000000056200000000000000000000000000000000000000000000000000000000000005590000000000000000000000000000000000000000000000000000000000000563000000000000000000000000000000000000000000000000000000000000055a0000000000000000000000000000000000000000000000000000000000000564000000000000000000000000000000000000000000000000000000000000055b0000000000000000000000000000000000000000000000000000000000000565000000000000000000000000000000000000000000000000000000000000055c0000000000000000000000000000000000000000000000000000000000000566000000000000000000000000000000000000000000000000000000000000055d0000000000000000000000000000000000000000000000000000000000000567000000000000000000000000000000000000000000000000000000000000055e0000000000000000000000000000000000000000000000000000000000000568000000000000000000000000000000000000000000000000000000000000055f0000000000000000000000000000000000000000000000000000000000000569000000000000000000400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000018100000000000000000000000000000000000000000000000000000000000001820000000000000000000000000000000000000000000000000000000000000183000000000000000000000000000000000000000000000000000000000000018400000000000000000000000000000000000000000000000000000000000001850000000000000000000000000000000000000000000000000000000000000186000000000000000000000000000000000000000000000000000000000000018700000000000000000000000000000000000000000000000000000000000001880000000000000000000000000000000000000000000000000000000000000189000000000000000000000000000000000000000000000000000000000000018a000000000000000000000000000000000000000000000000000000000000018b000000000000000000000000000000000000000000000000000000000000018c000000000000000000000000000000000000000000000000000000000000018d000000000000000000000000000000000000000000000000000000000000018e000000000000000000000000000000000000000000000000000000000000018f0000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000019100000000000000000000000000000000000000000000000000000000000001920000000000000000000000000000000000000000000000000000000000000193000000000000000000000000000000000000000000000000000000000000019400000000000000000000000000000000000000000000000000000000000001950000000000000000000000000000000000000000000000000000000000000196000000000000000000000000000000000000000000000000000000000000019700000000000000000000000000000000000000000000000000000000000001980000000000000000000000000000000000000000000000000000000000000199000000000000000000000000000000000000000000000000000000000000019a000000000000000000000000000000000000000000000000000000000000019b000000000000000000000000000000000000000000000000000000000000019c000000000000000000000000000000000000000000000000000000000000019d000000000000000000000000000000000000000000000000000000000000019e000000000000000000000000000000000000000000000000000000000000019f00000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001a100000000000000000000000000000000000000000000000000000000000001a200000000000000000000000000000000000000000000000000000000000001a300000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000000001a500000000000000000000000000000000000000000000000000000000000001a600000000000000000000000000000000000000000000000000000000000001a700000000000000000000000000000000000000000000000000000000000001a800000000000000000000000000000000000000000000000000000000000001a900000000000000000000000000000000000000000000000000000000000001aa00000000000000000000000000000000000000000000000000000000000001ab00000000000000000000000000000000000000000000000000000000000001ac00000000000000000000000000000000000000000000000000000000000001ad00000000000000000000000000000000000000000000000000000000000001ae00000000000000000000000000000000000000000000000000000000000001af00000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001b100000000000000000000000000000000000000000000000000000000000001b200000000000000000000000000000000000000000000000000000000000001b300000000000000000000000000000000000000000000000000000000000001b400000000000000000000000000000000000000000000000000000000000001b500000000000000000000000000000000000000000000000000000000000001b600000000000000000000000000000000000000000000000000000000000001b700000000000000000000000000000000000000000000000000000000000001b800000000000000000000000000000000000000000000000000000000000001b900000000000000000000000000000000000000000000000000000000000001ba00000000000000000000000000000000000000000000000000000000000001bb00000000000000000000000000000000000000000000000000000000000001bc00000000000000000000000000000000000000000000000000000000000001bd00000000000000000000000000000000000000000000000000000000000001be00000000000000000000000000000000000000000000000000000000000001bf3f0000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000028100000000000000000000000000000000000000000000000000000000000002820000000000000000000000000000000000000000000000000000000000000283000000000000000000000000000000000000000000000000000000000000028400000000000000000000000000000000000000000000000000000000000002850000000000000000000000000000000000000000000000000000000000000286000000000000000000000000000000000000000000000000000000000000028700000000000000000000000000000000000000000000000000000000000002880000000000000000000000000000000000000000000000000000000000000289000000000000000000000000000000000000000000000000000000000000028a000000000000000000000000000000000000000000000000000000000000028b000000000000000000000000000000000000000000000000000000000000028c000000000000000000000000000000000000000000000000000000000000028d000000000000000000000000000000000000000000000000000000000000028e000000000000000000000000000000000000000000000000000000000000028f0000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000029100000000000000000000000000000000000000000000000000000000000002920000000000000000000000000000000000000000000000000000000000000293000000000000000000000000000000000000000000000000000000000000029400000000000000000000000000000000000000000000000000000000000002950000000000000000000000000000000000000000000000000000000000000296000000000000000000000000000000000000000000000000000000000000029700000000000000000000000000000000000000000000000000000000000002980000000000000000000000000000000000000000000000000000000000000299000000000000000000000000000000000000000000000000000000000000029a000000000000000000000000000000000000000000000000000000000000029b000000000000000000000000000000000000000000000000000000000000029c000000000000000000000000000000000000000000000000000000000000029d000000000000000000000000000000000000000000000000000000000000029e000000000000000000000000000000000000000000000000000000000000029f00000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002a100000000000000000000000000000000000000000000000000000000000002a200000000000000000000000000000000000000000000000000000000000002a300000000000000000000000000000000000000000000000000000000000002a400000000000000000000000000000000000000000000000000000000000002a500000000000000000000000000000000000000000000000000000000000002a600000000000000000000000000000000000000000000000000000000000002a700000000000000000000000000000000000000000000000000000000000002a800000000000000000000000000000000000000000000000000000000000002a900000000000000000000000000000000000000000000000000000000000002aa00000000000000000000000000000000000000000000000000000000000002ab00000000000000000000000000000000000000000000000000000000000002ac00000000000000000000000000000000000000000000000000000000000002ad00000000000000000000000000000000000000000000000000000000000002ae00000000000000000000000000000000000000000000000000000000000002af00000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002b100000000000000000000000000000000000000000000000000000000000002b200000000000000000000000000000000000000000000000000000000000002b300000000000000000000000000000000000000000000000000000000000002b400000000000000000000000000000000000000000000000000000000000002b500000000000000000000000000000000000000000000000000000000000002b600000000000000000000000000000000000000000000000000000000000002b700000000000000000000000000000000000000000000000000000000000002b800000000000000000000000000000000000000000000000000000000000002b900000000000000000000000000000000000000000000000000000000000002ba00000000000000000000000000000000000000000000000000000000000002bb00000000000000000000000000000000000000000000000000000000000002bc00000000000000000000000000000000000000000000000000000000000002bd00000000000000000000000000000000000000000000000000000000000002be0200000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000381200000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000058a0000000000000000000000000000000000000000000000000000000000000581000000000000000000000000000000000000000000000000000000000000058b0000000000000000000000000000000000000000000000000000000000000582000000000000000000000000000000000000000000000000000000000000058c0000000000000000000000000000000000000000000000000000000000000583000000000000000000000000000000000000000000000000000000000000058d0000000000000000000000000000000000000000000000000000000000000584000000000000000000000000000000000000000000000000000000000000058e0000000000000000000000000000000000000000000000000000000000000585000000000000000000000000000000000000000000000000000000000000058f00000000000000000000000000000000000000000000000000000000000005860000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000058700000000000000000000000000000000000000000000000000000000000005910000000000000000000000000000000000000000000000000000000000000588000000000000000000000000000000000000000000000000000000000000059200000000000000000000000000000000000000000000000000000000000005890000000000000000000000000000000000000000000000000000000000000593000000000000000000000000000000000000000000000000000000000000058a0000000000000000000000000000000000000000000000000000000000000594000000000000000000000000000000000000000000000000000000000000058b0000000000000000000000000000000000000000000000000000000000000595000000000000000000000000000000000000000000000000000000000000058c0000000000000000000000000000000000000000000000000000000000000596000000000000000000000000000000000000000000000000000000000000058d0000000000000000000000000000000000000000000000000000000000000597000000000000000000000000000000000000000000000000000000000000058e0000000000000000000000000000000000000000000000000000000000000598000000000000000000000000000000000000000000000000000000000000058f00000000000000000000000000000000000000000000000000000000000005990000000000000000000000000000000000000000000000000000000000000590000000000000000000000000000000000000000000000000000000000000059a0000000000000000000000000000000000000000000000000000000000000591000000000000000000000000000000000000000000000000000000000000059b0000000000000000000000000000000000000000000000000000000000000592000000000000000000000000000000000000000000000000000000000000059c0000000000000000000000000000000000000000000000000000000000000593000000000000000000000000000000000000000000000000000000000000059d0000000000000000000000000000000000000000000000000000000000000594000000000000000000000000000000000000000000000000000000000000059e0000000000000000000000000000000000000000000000000000000000000595000000000000000000000000000000000000000000000000000000000000059f000000000000000000000000000000000000000000000000000000000000059600000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000059700000000000000000000000000000000000000000000000000000000000005a1000000000000000000000000000000000000000000000000000000000000059800000000000000000000000000000000000000000000000000000000000005a2000000000000000000000000000000000000000000000000000000000000059900000000000000000000000000000000000000000000000000000000000005a3000000000000000000000000000000000000000000000000000000000000059a00000000000000000000000000000000000000000000000000000000000005a4000000000000000000000000000000000000000000000000000000000000059b00000000000000000000000000000000000000000000000000000000000005a5000000000000000000000000000000000000000000000000000000000000059c00000000000000000000000000000000000000000000000000000000000005a6000000000000000000000000000000000000000000000000000000000000059d00000000000000000000000000000000000000000000000000000000000005a7000000000000000000000000000000000000000000000000000000000000059e00000000000000000000000000000000000000000000000000000000000005a8000000000000000000000000000000000000000000000000000000000000059f00000000000000000000000000000000000000000000000000000000000005a90000000000000000004000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001c100000000000000000000000000000000000000000000000000000000000001c200000000000000000000000000000000000000000000000000000000000001c300000000000000000000000000000000000000000000000000000000000001c400000000000000000000000000000000000000000000000000000000000001c500000000000000000000000000000000000000000000000000000000000001c600000000000000000000000000000000000000000000000000000000000001c700000000000000000000000000000000000000000000000000000000000001c800000000000000000000000000000000000000000000000000000000000001c900000000000000000000000000000000000000000000000000000000000001ca00000000000000000000000000000000000000000000000000000000000001cb00000000000000000000000000000000000000000000000000000000000001cc00000000000000000000000000000000000000000000000000000000000001cd00000000000000000000000000000000000000000000000000000000000001ce00000000000000000000000000000000000000000000000000000000000001cf00000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000001d100000000000000000000000000000000000000000000000000000000000001d200000000000000000000000000000000000000000000000000000000000001d300000000000000000000000000000000000000000000000000000000000001d400000000000000000000000000000000000000000000000000000000000001d500000000000000000000000000000000000000000000000000000000000001d600000000000000000000000000000000000000000000000000000000000001d700000000000000000000000000000000000000000000000000000000000001d800000000000000000000000000000000000000000000000000000000000001d900000000000000000000000000000000000000000000000000000000000001da00000000000000000000000000000000000000000000000000000000000001db00000000000000000000000000000000000000000000000000000000000001dc00000000000000000000000000000000000000000000000000000000000001dd00000000000000000000000000000000000000000000000000000000000001de00000000000000000000000000000000000000000000000000000000000001df00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001e100000000000000000000000000000000000000000000000000000000000001e200000000000000000000000000000000000000000000000000000000000001e300000000000000000000000000000000000000000000000000000000000001e400000000000000000000000000000000000000000000000000000000000001e500000000000000000000000000000000000000000000000000000000000001e600000000000000000000000000000000000000000000000000000000000001e700000000000000000000000000000000000000000000000000000000000001e800000000000000000000000000000000000000000000000000000000000001e900000000000000000000000000000000000000000000000000000000000001ea00000000000000000000000000000000000000000000000000000000000001eb00000000000000000000000000000000000000000000000000000000000001ec00000000000000000000000000000000000000000000000000000000000001ed00000000000000000000000000000000000000000000000000000000000001ee00000000000000000000000000000000000000000000000000000000000001ef00000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000001f100000000000000000000000000000000000000000000000000000000000001f200000000000000000000000000000000000000000000000000000000000001f300000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001f500000000000000000000000000000000000000000000000000000000000001f600000000000000000000000000000000000000000000000000000000000001f700000000000000000000000000000000000000000000000000000000000001f800000000000000000000000000000000000000000000000000000000000001f900000000000000000000000000000000000000000000000000000000000001fa00000000000000000000000000000000000000000000000000000000000001fb00000000000000000000000000000000000000000000000000000000000001fc00000000000000000000000000000000000000000000000000000000000001fd00000000000000000000000000000000000000000000000000000000000001fe00000000000000000000000000000000000000000000000000000000000001ff3f00000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000002c100000000000000000000000000000000000000000000000000000000000002c200000000000000000000000000000000000000000000000000000000000002c300000000000000000000000000000000000000000000000000000000000002c400000000000000000000000000000000000000000000000000000000000002c500000000000000000000000000000000000000000000000000000000000002c600000000000000000000000000000000000000000000000000000000000002c700000000000000000000000000000000000000000000000000000000000002c800000000000000000000000000000000000000000000000000000000000002c900000000000000000000000000000000000000000000000000000000000002ca00000000000000000000000000000000000000000000000000000000000002cb00000000000000000000000000000000000000000000000000000000000002cc00000000000000000000000000000000000000000000000000000000000002cd00000000000000000000000000000000000000000000000000000000000002ce00000000000000000000000000000000000000000000000000000000000002cf00000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000002d100000000000000000000000000000000000000000000000000000000000002d200000000000000000000000000000000000000000000000000000000000002d300000000000000000000000000000000000000000000000000000000000002d400000000000000000000000000000000000000000000000000000000000002d500000000000000000000000000000000000000000000000000000000000002d600000000000000000000000000000000000000000000000000000000000002d700000000000000000000000000000000000000000000000000000000000002d800000000000000000000000000000000000000000000000000000000000002d900000000000000000000000000000000000000000000000000000000000002da00000000000000000000000000000000000000000000000000000000000002db00000000000000000000000000000000000000000000000000000000000002dc00000000000000000000000000000000000000000000000000000000000002dd00000000000000000000000000000000000000000000000000000000000002de00000000000000000000000000000000000000000000000000000000000002df00000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000002e100000000000000000000000000000000000000000000000000000000000002e200000000000000000000000000000000000000000000000000000000000002e300000000000000000000000000000000000000000000000000000000000002e400000000000000000000000000000000000000000000000000000000000002e500000000000000000000000000000000000000000000000000000000000002e600000000000000000000000000000000000000000000000000000000000002e700000000000000000000000000000000000000000000000000000000000002e800000000000000000000000000000000000000000000000000000000000002e900000000000000000000000000000000000000000000000000000000000002ea00000000000000000000000000000000000000000000000000000000000002eb00000000000000000000000000000000000000000000000000000000000002ec00000000000000000000000000000000000000000000000000000000000002ed00000000000000000000000000000000000000000000000000000000000002ee00000000000000000000000000000000000000000000000000000000000002ef00000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f100000000000000000000000000000000000000000000000000000000000002f200000000000000000000000000000000000000000000000000000000000002f300000000000000000000000000000000000000000000000000000000000002f400000000000000000000000000000000000000000000000000000000000002f500000000000000000000000000000000000000000000000000000000000002f600000000000000000000000000000000000000000000000000000000000002f700000000000000000000000000000000000000000000000000000000000002f800000000000000000000000000000000000000000000000000000000000002f900000000000000000000000000000000000000000000000000000000000002fa00000000000000000000000000000000000000000000000000000000000002fb00000000000000000000000000000000000000000000000000000000000002fc00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000002fe0200000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c12000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000005ca00000000000000000000000000000000000000000000000000000000000005c100000000000000000000000000000000000000000000000000000000000005cb00000000000000000000000000000000000000000000000000000000000005c200000000000000000000000000000000000000000000000000000000000005cc00000000000000000000000000000000000000000000000000000000000005c300000000000000000000000000000000000000000000000000000000000005cd00000000000000000000000000000000000000000000000000000000000005c400000000000000000000000000000000000000000000000000000000000005ce00000000000000000000000000000000000000000000000000000000000005c500000000000000000000000000000000000000000000000000000000000005cf00000000000000000000000000000000000000000000000000000000000005c600000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000005c700000000000000000000000000000000000000000000000000000000000005d100000000000000000000000000000000000000000000000000000000000005c800000000000000000000000000000000000000000000000000000000000005d200000000000000000000000000000000000000000000000000000000000005c900000000000000000000000000000000000000000000000000000000000005d300000000000000000000000000000000000000000000000000000000000005ca00000000000000000000000000000000000000000000000000000000000005d400000000000000000000000000000000000000000000000000000000000005cb00000000000000000000000000000000000000000000000000000000000005d500000000000000000000000000000000000000000000000000000000000005cc00000000000000000000000000000000000000000000000000000000000005d600000000000000000000000000000000000000000000000000000000000005cd00000000000000000000000000000000000000000000000000000000000005d700000000000000000000000000000000000000000000000000000000000005ce00000000000000000000000000000000000000000000000000000000000005d800000000000000000000000000000000000000000000000000000000000005cf00000000000000000000000000000000000000000000000000000000000005d900000000000000000000000000000000000000000000000000000000000005d000000000000000000000000000000000000000000000000000000000000005da00000000000000000000000000000000000000000000000000000000000005d100000000000000000000000000000000000000000000000000000000000005db00000000000000000000000000000000000000000000000000000000000005d200000000000000000000000000000000000000000000000000000000000005dc00000000000000000000000000000000000000000000000000000000000005d300000000000000000000000000000000000000000000000000000000000005dd00000000000000000000000000000000000000000000000000000000000005d400000000000000000000000000000000000000000000000000000000000005de00000000000000000000000000000000000000000000000000000000000005d500000000000000000000000000000000000000000000000000000000000005df00000000000000000000000000000000000000000000000000000000000005d600000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000005d700000000000000000000000000000000000000000000000000000000000005e100000000000000000000000000000000000000000000000000000000000005d800000000000000000000000000000000000000000000000000000000000005e200000000000000000000000000000000000000000000000000000000000005d900000000000000000000000000000000000000000000000000000000000005e300000000000000000000000000000000000000000000000000000000000005da00000000000000000000000000000000000000000000000000000000000005e400000000000000000000000000000000000000000000000000000000000005db00000000000000000000000000000000000000000000000000000000000005e500000000000000000000000000000000000000000000000000000000000005dc00000000000000000000000000000000000000000000000000000000000005e600000000000000000000000000000000000000000000000000000000000005dd00000000000000000000000000000000000000000000000000000000000005e700000000000000000000000000000000000000000000000000000000000005de00000000000000000000000000000000000000000000000000000000000005e800000000000000000000000000000000000000000000000000000000000005df00000000000000000000000000000000000000000000000000000000000005e9000000000000000000400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020100000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000000000000000000000000000000000020400000000000000000000000000000000000000000000000000000000000002050000000000000000000000000000000000000000000000000000000000000206000000000000000000000000000000000000000000000000000000000000020700000000000000000000000000000000000000000000000000000000000002080000000000000000000000000000000000000000000000000000000000000209000000000000000000000000000000000000000000000000000000000000020a000000000000000000000000000000000000000000000000000000000000020b000000000000000000000000000000000000000000000000000000000000020c000000000000000000000000000000000000000000000000000000000000020d000000000000000000000000000000000000000000000000000000000000020e000000000000000000000000000000000000000000000000000000000000020f0000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000000000000021100000000000000000000000000000000000000000000000000000000000002120000000000000000000000000000000000000000000000000000000000000213000000000000000000000000000000000000000000000000000000000000021400000000000000000000000000000000000000000000000000000000000002150000000000000000000000000000000000000000000000000000000000000216000000000000000000000000000000000000000000000000000000000000021700000000000000000000000000000000000000000000000000000000000002180000000000000000000000000000000000000000000000000000000000000219000000000000000000000000000000000000000000000000000000000000021a000000000000000000000000000000000000000000000000000000000000021b000000000000000000000000000000000000000000000000000000000000021c000000000000000000000000000000000000000000000000000000000000021d000000000000000000000000000000000000000000000000000000000000021e000000000000000000000000000000000000000000000000000000000000021f0000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000022100000000000000000000000000000000000000000000000000000000000002220000000000000000000000000000000000000000000000000000000000000223000000000000000000000000000000000000000000000000000000000000022400000000000000000000000000000000000000000000000000000000000002250000000000000000000000000000000000000000000000000000000000000226000000000000000000000000000000000000000000000000000000000000022700000000000000000000000000000000000000000000000000000000000002280000000000000000000000000000000000000000000000000000000000000229000000000000000000000000000000000000000000000000000000000000022a000000000000000000000000000000000000000000000000000000000000022b000000000000000000000000000000000000000000000000000000000000022c000000000000000000000000000000000000000000000000000000000000022d000000000000000000000000000000000000000000000000000000000000022e000000000000000000000000000000000000000000000000000000000000022f0000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000023100000000000000000000000000000000000000000000000000000000000002320000000000000000000000000000000000000000000000000000000000000233000000000000000000000000000000000000000000000000000000000000023400000000000000000000000000000000000000000000000000000000000002350000000000000000000000000000000000000000000000000000000000000236000000000000000000000000000000000000000000000000000000000000023700000000000000000000000000000000000000000000000000000000000002380000000000000000000000000000000000000000000000000000000000000239000000000000000000000000000000000000000000000000000000000000023a000000000000000000000000000000000000000000000000000000000000023b000000000000000000000000000000000000000000000000000000000000023c000000000000000000000000000000000000000000000000000000000000023d000000000000000000000000000000000000000000000000000000000000023e000000000000000000000000000000000000000000000000000000000000023f3f0000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030100000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000003050000000000000000000000000000000000000000000000000000000000000306000000000000000000000000000000000000000000000000000000000000030700000000000000000000000000000000000000000000000000000000000003080000000000000000000000000000000000000000000000000000000000000309000000000000000000000000000000000000000000000000000000000000030a000000000000000000000000000000000000000000000000000000000000030b000000000000000000000000000000000000000000000000000000000000030c000000000000000000000000000000000000000000000000000000000000030d000000000000000000000000000000000000000000000000000000000000030e000000000000000000000000000000000000000000000000000000000000030f0000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000031100000000000000000000000000000000000000000000000000000000000003120000000000000000000000000000000000000000000000000000000000000313000000000000000000000000000000000000000000000000000000000000031400000000000000000000000000000000000000000000000000000000000003150000000000000000000000000000000000000000000000000000000000000316000000000000000000000000000000000000000000000000000000000000031700000000000000000000000000000000000000000000000000000000000003180000000000000000000000000000000000000000000000000000000000000319000000000000000000000000000000000000000000000000000000000000031a000000000000000000000000000000000000000000000000000000000000031b000000000000000000000000000000000000000000000000000000000000031c000000000000000000000000000000000000000000000000000000000000031d000000000000000000000000000000000000000000000000000000000000031e000000000000000000000000000000000000000000000000000000000000031f0000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032100000000000000000000000000000000000000000000000000000000000003220000000000000000000000000000000000000000000000000000000000000323000000000000000000000000000000000000000000000000000000000000032400000000000000000000000000000000000000000000000000000000000003250000000000000000000000000000000000000000000000000000000000000326000000000000000000000000000000000000000000000000000000000000032700000000000000000000000000000000000000000000000000000000000003280000000000000000000000000000000000000000000000000000000000000329000000000000000000000000000000000000000000000000000000000000032a000000000000000000000000000000000000000000000000000000000000032b000000000000000000000000000000000000000000000000000000000000032c000000000000000000000000000000000000000000000000000000000000032d000000000000000000000000000000000000000000000000000000000000032e000000000000000000000000000000000000000000000000000000000000032f0000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033100000000000000000000000000000000000000000000000000000000000003320000000000000000000000000000000000000000000000000000000000000333000000000000000000000000000000000000000000000000000000000000033400000000000000000000000000000000000000000000000000000000000003350000000000000000000000000000000000000000000000000000000000000336000000000000000000000000000000000000000000000000000000000000033700000000000000000000000000000000000000000000000000000000000003380000000000000000000000000000000000000000000000000000000000000339000000000000000000000000000000000000000000000000000000000000033a000000000000000000000000000000000000000000000000000000000000033b000000000000000000000000000000000000000000000000000000000000033c000000000000000000000000000000000000000000000000000000000000033d000000000000000000000000000000000000000000000000000000000000033e0200000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000401200000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060a0000000000000000000000000000000000000000000000000000000000000601000000000000000000000000000000000000000000000000000000000000060b0000000000000000000000000000000000000000000000000000000000000602000000000000000000000000000000000000000000000000000000000000060c0000000000000000000000000000000000000000000000000000000000000603000000000000000000000000000000000000000000000000000000000000060d0000000000000000000000000000000000000000000000000000000000000604000000000000000000000000000000000000000000000000000000000000060e0000000000000000000000000000000000000000000000000000000000000605000000000000000000000000000000000000000000000000000000000000060f00000000000000000000000000000000000000000000000000000000000006060000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000060700000000000000000000000000000000000000000000000000000000000006110000000000000000000000000000000000000000000000000000000000000608000000000000000000000000000000000000000000000000000000000000061200000000000000000000000000000000000000000000000000000000000006090000000000000000000000000000000000000000000000000000000000000613000000000000000000000000000000000000000000000000000000000000060a0000000000000000000000000000000000000000000000000000000000000614000000000000000000000000000000000000000000000000000000000000060b0000000000000000000000000000000000000000000000000000000000000615000000000000000000000000000000000000000000000000000000000000060c0000000000000000000000000000000000000000000000000000000000000616000000000000000000000000000000000000000000000000000000000000060d0000000000000000000000000000000000000000000000000000000000000617000000000000000000000000000000000000000000000000000000000000060e0000000000000000000000000000000000000000000000000000000000000618000000000000000000000000000000000000000000000000000000000000060f00000000000000000000000000000000000000000000000000000000000006190000000000000000000000000000000000000000000000000000000000000610000000000000000000000000000000000000000000000000000000000000061a0000000000000000000000000000000000000000000000000000000000000611000000000000000000000000000000000000000000000000000000000000061b0000000000000000000000000000000000000000000000000000000000000612000000000000000000000000000000000000000000000000000000000000061c0000000000000000000000000000000000000000000000000000000000000613000000000000000000000000000000000000000000000000000000000000061d0000000000000000000000000000000000000000000000000000000000000614000000000000000000000000000000000000000000000000000000000000061e0000000000000000000000000000000000000000000000000000000000000615000000000000000000000000000000000000000000000000000000000000061f00000000000000000000000000000000000000000000000000000000000006160000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000061700000000000000000000000000000000000000000000000000000000000006210000000000000000000000000000000000000000000000000000000000000618000000000000000000000000000000000000000000000000000000000000062200000000000000000000000000000000000000000000000000000000000006190000000000000000000000000000000000000000000000000000000000000623000000000000000000000000000000000000000000000000000000000000061a0000000000000000000000000000000000000000000000000000000000000624000000000000000000000000000000000000000000000000000000000000061b0000000000000000000000000000000000000000000000000000000000000625000000000000000000000000000000000000000000000000000000000000061c0000000000000000000000000000000000000000000000000000000000000626000000000000000000000000000000000000000000000000000000000000061d0000000000000000000000000000000000000000000000000000000000000627000000000000000000000000000000000000000000000000000000000000061e0000000000000000000000000000000000000000000000000000000000000628000000000000000000000000000000000000000000000000000000000000061f00000000000000000000000000000000000000000000000000000000000006290000000000000000", "txsEffectsHash": "0x0097a976d5a0b2aa3ea4f9a657d4a8534ed793f49287da441c5d301adfd10d2a", "decodedHeader": { @@ -49,8 +49,8 @@ "chainId": 31337, "timestamp": 0, "version": 1, - "coinbase": "0xfefb7bf9e18d6ebc9e57c5382f9b2708ad0225d5", - "feeRecipient": "0x26a12e4e18661b750e93a1b2a0ee5ab12232135ea95cf6616fae8e8d9616f169", + "coinbase": "0xcb433ad76e9fe9c41059c27d265df41d9acbf5ff", + "feeRecipient": "0x232da3781f3971d8f6cb0246fd911a893453ef41346cbc81b495f4d887f9a1e3", "gasFees": { "feePerDaGas": 0, "feePerL1Gas": 0, @@ -82,8 +82,8 @@ } } }, - "header": "0x05b0b6df52f1d47d0406318558052c89a174fbc9d615def82b3cc9ccc1937db80000000100000000000000000000000000000000000000000000000000000000000000020097a976d5a0b2aa3ea4f9a657d4a8534ed793f49287da441c5d301adfd10d2a00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00198704eb051da0e43ff1a9b3285f168389ba3dd93f8ec1f75f6cafcadbaeb61864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000100d944282e11bdcfa5e8f2b55fe80db4c586087bfc10e0bbba5724d30b8c15e2e0000010001c16141039343d4d403501e66deecff1b024bd76794820a43dc3424087813a20000018028d06967b6a4a1cc3c799fb6f008b63a2ffecd5034b81aa10792a6659f8aca22000000c00000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000fefb7bf9e18d6ebc9e57c5382f9b2708ad0225d526a12e4e18661b750e93a1b2a0ee5ab12232135ea95cf6616fae8e8d9616f169000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "publicInputsHash": "0x00444e4b646e6d848f610abdb4b1c5d019b47e10da1d0f16d01f52c4fabda4a9", + "header": "0x05b0b6df52f1d47d0406318558052c89a174fbc9d615def82b3cc9ccc1937db80000000100000000000000000000000000000000000000000000000000000000000000020097a976d5a0b2aa3ea4f9a657d4a8534ed793f49287da441c5d301adfd10d2a00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00198704eb051da0e43ff1a9b3285f168389ba3dd93f8ec1f75f6cafcadbaeb61864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000100d944282e11bdcfa5e8f2b55fe80db4c586087bfc10e0bbba5724d30b8c15e2e0000010001c16141039343d4d403501e66deecff1b024bd76794820a43dc3424087813a20000018028d06967b6a4a1cc3c799fb6f008b63a2ffecd5034b81aa10792a6659f8aca22000000c00000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000cb433ad76e9fe9c41059c27d265df41d9acbf5ff232da3781f3971d8f6cb0246fd911a893453ef41346cbc81b495f4d887f9a1e3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "publicInputsHash": "0x00e815938884265d230edf2de3b24aa1a8edf2e7fc0fcb65ed15cc6464a33afd", "numTxs": 4 } } \ No newline at end of file diff --git a/l1-contracts/test/fixtures/mixed_block_1.json b/l1-contracts/test/fixtures/mixed_block_1.json index 43f83bab720a..bfae6182e66b 100644 --- a/l1-contracts/test/fixtures/mixed_block_1.json +++ b/l1-contracts/test/fixtures/mixed_block_1.json @@ -34,7 +34,7 @@ ] }, "block": { - "archive": "0x15a231eb83543ddaf08fe316b80e48e50b065b7038ad4d9fec6465d060d7a300", + "archive": "0x1935c3506395eb1b6bc63839e01cd3aa2ca13a5b4ee3de54a1d42dcb00a7f856", "body": "0x0000000400400000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000024100000000000000000000000000000000000000000000000000000000000002420000000000000000000000000000000000000000000000000000000000000243000000000000000000000000000000000000000000000000000000000000024400000000000000000000000000000000000000000000000000000000000002450000000000000000000000000000000000000000000000000000000000000246000000000000000000000000000000000000000000000000000000000000024700000000000000000000000000000000000000000000000000000000000002480000000000000000000000000000000000000000000000000000000000000249000000000000000000000000000000000000000000000000000000000000024a000000000000000000000000000000000000000000000000000000000000024b000000000000000000000000000000000000000000000000000000000000024c000000000000000000000000000000000000000000000000000000000000024d000000000000000000000000000000000000000000000000000000000000024e000000000000000000000000000000000000000000000000000000000000024f0000000000000000000000000000000000000000000000000000000000000250000000000000000000000000000000000000000000000000000000000000025100000000000000000000000000000000000000000000000000000000000002520000000000000000000000000000000000000000000000000000000000000253000000000000000000000000000000000000000000000000000000000000025400000000000000000000000000000000000000000000000000000000000002550000000000000000000000000000000000000000000000000000000000000256000000000000000000000000000000000000000000000000000000000000025700000000000000000000000000000000000000000000000000000000000002580000000000000000000000000000000000000000000000000000000000000259000000000000000000000000000000000000000000000000000000000000025a000000000000000000000000000000000000000000000000000000000000025b000000000000000000000000000000000000000000000000000000000000025c000000000000000000000000000000000000000000000000000000000000025d000000000000000000000000000000000000000000000000000000000000025e000000000000000000000000000000000000000000000000000000000000025f0000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000026100000000000000000000000000000000000000000000000000000000000002620000000000000000000000000000000000000000000000000000000000000263000000000000000000000000000000000000000000000000000000000000026400000000000000000000000000000000000000000000000000000000000002650000000000000000000000000000000000000000000000000000000000000266000000000000000000000000000000000000000000000000000000000000026700000000000000000000000000000000000000000000000000000000000002680000000000000000000000000000000000000000000000000000000000000269000000000000000000000000000000000000000000000000000000000000026a000000000000000000000000000000000000000000000000000000000000026b000000000000000000000000000000000000000000000000000000000000026c000000000000000000000000000000000000000000000000000000000000026d000000000000000000000000000000000000000000000000000000000000026e000000000000000000000000000000000000000000000000000000000000026f0000000000000000000000000000000000000000000000000000000000000270000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000002720000000000000000000000000000000000000000000000000000000000000273000000000000000000000000000000000000000000000000000000000000027400000000000000000000000000000000000000000000000000000000000002750000000000000000000000000000000000000000000000000000000000000276000000000000000000000000000000000000000000000000000000000000027700000000000000000000000000000000000000000000000000000000000002780000000000000000000000000000000000000000000000000000000000000279000000000000000000000000000000000000000000000000000000000000027a000000000000000000000000000000000000000000000000000000000000027b000000000000000000000000000000000000000000000000000000000000027c000000000000000000000000000000000000000000000000000000000000027d000000000000000000000000000000000000000000000000000000000000027e000000000000000000000000000000000000000000000000000000000000027f3f0000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000003420000000000000000000000000000000000000000000000000000000000000343000000000000000000000000000000000000000000000000000000000000034400000000000000000000000000000000000000000000000000000000000003450000000000000000000000000000000000000000000000000000000000000346000000000000000000000000000000000000000000000000000000000000034700000000000000000000000000000000000000000000000000000000000003480000000000000000000000000000000000000000000000000000000000000349000000000000000000000000000000000000000000000000000000000000034a000000000000000000000000000000000000000000000000000000000000034b000000000000000000000000000000000000000000000000000000000000034c000000000000000000000000000000000000000000000000000000000000034d000000000000000000000000000000000000000000000000000000000000034e000000000000000000000000000000000000000000000000000000000000034f0000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000035100000000000000000000000000000000000000000000000000000000000003520000000000000000000000000000000000000000000000000000000000000353000000000000000000000000000000000000000000000000000000000000035400000000000000000000000000000000000000000000000000000000000003550000000000000000000000000000000000000000000000000000000000000356000000000000000000000000000000000000000000000000000000000000035700000000000000000000000000000000000000000000000000000000000003580000000000000000000000000000000000000000000000000000000000000359000000000000000000000000000000000000000000000000000000000000035a000000000000000000000000000000000000000000000000000000000000035b000000000000000000000000000000000000000000000000000000000000035c000000000000000000000000000000000000000000000000000000000000035d000000000000000000000000000000000000000000000000000000000000035e000000000000000000000000000000000000000000000000000000000000035f0000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000036100000000000000000000000000000000000000000000000000000000000003620000000000000000000000000000000000000000000000000000000000000363000000000000000000000000000000000000000000000000000000000000036400000000000000000000000000000000000000000000000000000000000003650000000000000000000000000000000000000000000000000000000000000366000000000000000000000000000000000000000000000000000000000000036700000000000000000000000000000000000000000000000000000000000003680000000000000000000000000000000000000000000000000000000000000369000000000000000000000000000000000000000000000000000000000000036a000000000000000000000000000000000000000000000000000000000000036b000000000000000000000000000000000000000000000000000000000000036c000000000000000000000000000000000000000000000000000000000000036d000000000000000000000000000000000000000000000000000000000000036e000000000000000000000000000000000000000000000000000000000000036f0000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000037100000000000000000000000000000000000000000000000000000000000003720000000000000000000000000000000000000000000000000000000000000373000000000000000000000000000000000000000000000000000000000000037400000000000000000000000000000000000000000000000000000000000003750000000000000000000000000000000000000000000000000000000000000376000000000000000000000000000000000000000000000000000000000000037700000000000000000000000000000000000000000000000000000000000003780000000000000000000000000000000000000000000000000000000000000379000000000000000000000000000000000000000000000000000000000000037a000000000000000000000000000000000000000000000000000000000000037b000000000000000000000000000000000000000000000000000000000000037c000000000000000000000000000000000000000000000000000000000000037d000000000000000000000000000000000000000000000000000000000000037e0200000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000441200000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000064a0000000000000000000000000000000000000000000000000000000000000641000000000000000000000000000000000000000000000000000000000000064b0000000000000000000000000000000000000000000000000000000000000642000000000000000000000000000000000000000000000000000000000000064c0000000000000000000000000000000000000000000000000000000000000643000000000000000000000000000000000000000000000000000000000000064d0000000000000000000000000000000000000000000000000000000000000644000000000000000000000000000000000000000000000000000000000000064e0000000000000000000000000000000000000000000000000000000000000645000000000000000000000000000000000000000000000000000000000000064f00000000000000000000000000000000000000000000000000000000000006460000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000064700000000000000000000000000000000000000000000000000000000000006510000000000000000000000000000000000000000000000000000000000000648000000000000000000000000000000000000000000000000000000000000065200000000000000000000000000000000000000000000000000000000000006490000000000000000000000000000000000000000000000000000000000000653000000000000000000000000000000000000000000000000000000000000064a0000000000000000000000000000000000000000000000000000000000000654000000000000000000000000000000000000000000000000000000000000064b0000000000000000000000000000000000000000000000000000000000000655000000000000000000000000000000000000000000000000000000000000064c0000000000000000000000000000000000000000000000000000000000000656000000000000000000000000000000000000000000000000000000000000064d0000000000000000000000000000000000000000000000000000000000000657000000000000000000000000000000000000000000000000000000000000064e0000000000000000000000000000000000000000000000000000000000000658000000000000000000000000000000000000000000000000000000000000064f00000000000000000000000000000000000000000000000000000000000006590000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000065a0000000000000000000000000000000000000000000000000000000000000651000000000000000000000000000000000000000000000000000000000000065b0000000000000000000000000000000000000000000000000000000000000652000000000000000000000000000000000000000000000000000000000000065c0000000000000000000000000000000000000000000000000000000000000653000000000000000000000000000000000000000000000000000000000000065d0000000000000000000000000000000000000000000000000000000000000654000000000000000000000000000000000000000000000000000000000000065e0000000000000000000000000000000000000000000000000000000000000655000000000000000000000000000000000000000000000000000000000000065f00000000000000000000000000000000000000000000000000000000000006560000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000065700000000000000000000000000000000000000000000000000000000000006610000000000000000000000000000000000000000000000000000000000000658000000000000000000000000000000000000000000000000000000000000066200000000000000000000000000000000000000000000000000000000000006590000000000000000000000000000000000000000000000000000000000000663000000000000000000000000000000000000000000000000000000000000065a0000000000000000000000000000000000000000000000000000000000000664000000000000000000000000000000000000000000000000000000000000065b0000000000000000000000000000000000000000000000000000000000000665000000000000000000000000000000000000000000000000000000000000065c0000000000000000000000000000000000000000000000000000000000000666000000000000000000000000000000000000000000000000000000000000065d0000000000000000000000000000000000000000000000000000000000000667000000000000000000000000000000000000000000000000000000000000065e0000000000000000000000000000000000000000000000000000000000000668000000000000000000000000000000000000000000000000000000000000065f0000000000000000000000000000000000000000000000000000000000000669000000000000000000400000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000028100000000000000000000000000000000000000000000000000000000000002820000000000000000000000000000000000000000000000000000000000000283000000000000000000000000000000000000000000000000000000000000028400000000000000000000000000000000000000000000000000000000000002850000000000000000000000000000000000000000000000000000000000000286000000000000000000000000000000000000000000000000000000000000028700000000000000000000000000000000000000000000000000000000000002880000000000000000000000000000000000000000000000000000000000000289000000000000000000000000000000000000000000000000000000000000028a000000000000000000000000000000000000000000000000000000000000028b000000000000000000000000000000000000000000000000000000000000028c000000000000000000000000000000000000000000000000000000000000028d000000000000000000000000000000000000000000000000000000000000028e000000000000000000000000000000000000000000000000000000000000028f0000000000000000000000000000000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000029100000000000000000000000000000000000000000000000000000000000002920000000000000000000000000000000000000000000000000000000000000293000000000000000000000000000000000000000000000000000000000000029400000000000000000000000000000000000000000000000000000000000002950000000000000000000000000000000000000000000000000000000000000296000000000000000000000000000000000000000000000000000000000000029700000000000000000000000000000000000000000000000000000000000002980000000000000000000000000000000000000000000000000000000000000299000000000000000000000000000000000000000000000000000000000000029a000000000000000000000000000000000000000000000000000000000000029b000000000000000000000000000000000000000000000000000000000000029c000000000000000000000000000000000000000000000000000000000000029d000000000000000000000000000000000000000000000000000000000000029e000000000000000000000000000000000000000000000000000000000000029f00000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002a100000000000000000000000000000000000000000000000000000000000002a200000000000000000000000000000000000000000000000000000000000002a300000000000000000000000000000000000000000000000000000000000002a400000000000000000000000000000000000000000000000000000000000002a500000000000000000000000000000000000000000000000000000000000002a600000000000000000000000000000000000000000000000000000000000002a700000000000000000000000000000000000000000000000000000000000002a800000000000000000000000000000000000000000000000000000000000002a900000000000000000000000000000000000000000000000000000000000002aa00000000000000000000000000000000000000000000000000000000000002ab00000000000000000000000000000000000000000000000000000000000002ac00000000000000000000000000000000000000000000000000000000000002ad00000000000000000000000000000000000000000000000000000000000002ae00000000000000000000000000000000000000000000000000000000000002af00000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002b100000000000000000000000000000000000000000000000000000000000002b200000000000000000000000000000000000000000000000000000000000002b300000000000000000000000000000000000000000000000000000000000002b400000000000000000000000000000000000000000000000000000000000002b500000000000000000000000000000000000000000000000000000000000002b600000000000000000000000000000000000000000000000000000000000002b700000000000000000000000000000000000000000000000000000000000002b800000000000000000000000000000000000000000000000000000000000002b900000000000000000000000000000000000000000000000000000000000002ba00000000000000000000000000000000000000000000000000000000000002bb00000000000000000000000000000000000000000000000000000000000002bc00000000000000000000000000000000000000000000000000000000000002bd00000000000000000000000000000000000000000000000000000000000002be00000000000000000000000000000000000000000000000000000000000002bf3f0000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000038100000000000000000000000000000000000000000000000000000000000003820000000000000000000000000000000000000000000000000000000000000383000000000000000000000000000000000000000000000000000000000000038400000000000000000000000000000000000000000000000000000000000003850000000000000000000000000000000000000000000000000000000000000386000000000000000000000000000000000000000000000000000000000000038700000000000000000000000000000000000000000000000000000000000003880000000000000000000000000000000000000000000000000000000000000389000000000000000000000000000000000000000000000000000000000000038a000000000000000000000000000000000000000000000000000000000000038b000000000000000000000000000000000000000000000000000000000000038c000000000000000000000000000000000000000000000000000000000000038d000000000000000000000000000000000000000000000000000000000000038e000000000000000000000000000000000000000000000000000000000000038f0000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000039100000000000000000000000000000000000000000000000000000000000003920000000000000000000000000000000000000000000000000000000000000393000000000000000000000000000000000000000000000000000000000000039400000000000000000000000000000000000000000000000000000000000003950000000000000000000000000000000000000000000000000000000000000396000000000000000000000000000000000000000000000000000000000000039700000000000000000000000000000000000000000000000000000000000003980000000000000000000000000000000000000000000000000000000000000399000000000000000000000000000000000000000000000000000000000000039a000000000000000000000000000000000000000000000000000000000000039b000000000000000000000000000000000000000000000000000000000000039c000000000000000000000000000000000000000000000000000000000000039d000000000000000000000000000000000000000000000000000000000000039e000000000000000000000000000000000000000000000000000000000000039f00000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a100000000000000000000000000000000000000000000000000000000000003a200000000000000000000000000000000000000000000000000000000000003a300000000000000000000000000000000000000000000000000000000000003a400000000000000000000000000000000000000000000000000000000000003a500000000000000000000000000000000000000000000000000000000000003a600000000000000000000000000000000000000000000000000000000000003a700000000000000000000000000000000000000000000000000000000000003a800000000000000000000000000000000000000000000000000000000000003a900000000000000000000000000000000000000000000000000000000000003aa00000000000000000000000000000000000000000000000000000000000003ab00000000000000000000000000000000000000000000000000000000000003ac00000000000000000000000000000000000000000000000000000000000003ad00000000000000000000000000000000000000000000000000000000000003ae00000000000000000000000000000000000000000000000000000000000003af00000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003b100000000000000000000000000000000000000000000000000000000000003b200000000000000000000000000000000000000000000000000000000000003b300000000000000000000000000000000000000000000000000000000000003b400000000000000000000000000000000000000000000000000000000000003b500000000000000000000000000000000000000000000000000000000000003b600000000000000000000000000000000000000000000000000000000000003b700000000000000000000000000000000000000000000000000000000000003b800000000000000000000000000000000000000000000000000000000000003b900000000000000000000000000000000000000000000000000000000000003ba00000000000000000000000000000000000000000000000000000000000003bb00000000000000000000000000000000000000000000000000000000000003bc00000000000000000000000000000000000000000000000000000000000003bd00000000000000000000000000000000000000000000000000000000000003be0200000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000481200000000000000000000000000000000000000000000000000000000000000680000000000000000000000000000000000000000000000000000000000000068a0000000000000000000000000000000000000000000000000000000000000681000000000000000000000000000000000000000000000000000000000000068b0000000000000000000000000000000000000000000000000000000000000682000000000000000000000000000000000000000000000000000000000000068c0000000000000000000000000000000000000000000000000000000000000683000000000000000000000000000000000000000000000000000000000000068d0000000000000000000000000000000000000000000000000000000000000684000000000000000000000000000000000000000000000000000000000000068e0000000000000000000000000000000000000000000000000000000000000685000000000000000000000000000000000000000000000000000000000000068f00000000000000000000000000000000000000000000000000000000000006860000000000000000000000000000000000000000000000000000000000000690000000000000000000000000000000000000000000000000000000000000068700000000000000000000000000000000000000000000000000000000000006910000000000000000000000000000000000000000000000000000000000000688000000000000000000000000000000000000000000000000000000000000069200000000000000000000000000000000000000000000000000000000000006890000000000000000000000000000000000000000000000000000000000000693000000000000000000000000000000000000000000000000000000000000068a0000000000000000000000000000000000000000000000000000000000000694000000000000000000000000000000000000000000000000000000000000068b0000000000000000000000000000000000000000000000000000000000000695000000000000000000000000000000000000000000000000000000000000068c0000000000000000000000000000000000000000000000000000000000000696000000000000000000000000000000000000000000000000000000000000068d0000000000000000000000000000000000000000000000000000000000000697000000000000000000000000000000000000000000000000000000000000068e0000000000000000000000000000000000000000000000000000000000000698000000000000000000000000000000000000000000000000000000000000068f00000000000000000000000000000000000000000000000000000000000006990000000000000000000000000000000000000000000000000000000000000690000000000000000000000000000000000000000000000000000000000000069a0000000000000000000000000000000000000000000000000000000000000691000000000000000000000000000000000000000000000000000000000000069b0000000000000000000000000000000000000000000000000000000000000692000000000000000000000000000000000000000000000000000000000000069c0000000000000000000000000000000000000000000000000000000000000693000000000000000000000000000000000000000000000000000000000000069d0000000000000000000000000000000000000000000000000000000000000694000000000000000000000000000000000000000000000000000000000000069e0000000000000000000000000000000000000000000000000000000000000695000000000000000000000000000000000000000000000000000000000000069f000000000000000000000000000000000000000000000000000000000000069600000000000000000000000000000000000000000000000000000000000006a0000000000000000000000000000000000000000000000000000000000000069700000000000000000000000000000000000000000000000000000000000006a1000000000000000000000000000000000000000000000000000000000000069800000000000000000000000000000000000000000000000000000000000006a2000000000000000000000000000000000000000000000000000000000000069900000000000000000000000000000000000000000000000000000000000006a3000000000000000000000000000000000000000000000000000000000000069a00000000000000000000000000000000000000000000000000000000000006a4000000000000000000000000000000000000000000000000000000000000069b00000000000000000000000000000000000000000000000000000000000006a5000000000000000000000000000000000000000000000000000000000000069c00000000000000000000000000000000000000000000000000000000000006a6000000000000000000000000000000000000000000000000000000000000069d00000000000000000000000000000000000000000000000000000000000006a7000000000000000000000000000000000000000000000000000000000000069e00000000000000000000000000000000000000000000000000000000000006a8000000000000000000000000000000000000000000000000000000000000069f00000000000000000000000000000000000000000000000000000000000006a90000000000000000004000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000002c100000000000000000000000000000000000000000000000000000000000002c200000000000000000000000000000000000000000000000000000000000002c300000000000000000000000000000000000000000000000000000000000002c400000000000000000000000000000000000000000000000000000000000002c500000000000000000000000000000000000000000000000000000000000002c600000000000000000000000000000000000000000000000000000000000002c700000000000000000000000000000000000000000000000000000000000002c800000000000000000000000000000000000000000000000000000000000002c900000000000000000000000000000000000000000000000000000000000002ca00000000000000000000000000000000000000000000000000000000000002cb00000000000000000000000000000000000000000000000000000000000002cc00000000000000000000000000000000000000000000000000000000000002cd00000000000000000000000000000000000000000000000000000000000002ce00000000000000000000000000000000000000000000000000000000000002cf00000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000002d100000000000000000000000000000000000000000000000000000000000002d200000000000000000000000000000000000000000000000000000000000002d300000000000000000000000000000000000000000000000000000000000002d400000000000000000000000000000000000000000000000000000000000002d500000000000000000000000000000000000000000000000000000000000002d600000000000000000000000000000000000000000000000000000000000002d700000000000000000000000000000000000000000000000000000000000002d800000000000000000000000000000000000000000000000000000000000002d900000000000000000000000000000000000000000000000000000000000002da00000000000000000000000000000000000000000000000000000000000002db00000000000000000000000000000000000000000000000000000000000002dc00000000000000000000000000000000000000000000000000000000000002dd00000000000000000000000000000000000000000000000000000000000002de00000000000000000000000000000000000000000000000000000000000002df00000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000002e100000000000000000000000000000000000000000000000000000000000002e200000000000000000000000000000000000000000000000000000000000002e300000000000000000000000000000000000000000000000000000000000002e400000000000000000000000000000000000000000000000000000000000002e500000000000000000000000000000000000000000000000000000000000002e600000000000000000000000000000000000000000000000000000000000002e700000000000000000000000000000000000000000000000000000000000002e800000000000000000000000000000000000000000000000000000000000002e900000000000000000000000000000000000000000000000000000000000002ea00000000000000000000000000000000000000000000000000000000000002eb00000000000000000000000000000000000000000000000000000000000002ec00000000000000000000000000000000000000000000000000000000000002ed00000000000000000000000000000000000000000000000000000000000002ee00000000000000000000000000000000000000000000000000000000000002ef00000000000000000000000000000000000000000000000000000000000002f000000000000000000000000000000000000000000000000000000000000002f100000000000000000000000000000000000000000000000000000000000002f200000000000000000000000000000000000000000000000000000000000002f300000000000000000000000000000000000000000000000000000000000002f400000000000000000000000000000000000000000000000000000000000002f500000000000000000000000000000000000000000000000000000000000002f600000000000000000000000000000000000000000000000000000000000002f700000000000000000000000000000000000000000000000000000000000002f800000000000000000000000000000000000000000000000000000000000002f900000000000000000000000000000000000000000000000000000000000002fa00000000000000000000000000000000000000000000000000000000000002fb00000000000000000000000000000000000000000000000000000000000002fc00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000002ff3f00000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c100000000000000000000000000000000000000000000000000000000000003c200000000000000000000000000000000000000000000000000000000000003c300000000000000000000000000000000000000000000000000000000000003c400000000000000000000000000000000000000000000000000000000000003c500000000000000000000000000000000000000000000000000000000000003c600000000000000000000000000000000000000000000000000000000000003c700000000000000000000000000000000000000000000000000000000000003c800000000000000000000000000000000000000000000000000000000000003c900000000000000000000000000000000000000000000000000000000000003ca00000000000000000000000000000000000000000000000000000000000003cb00000000000000000000000000000000000000000000000000000000000003cc00000000000000000000000000000000000000000000000000000000000003cd00000000000000000000000000000000000000000000000000000000000003ce00000000000000000000000000000000000000000000000000000000000003cf00000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d100000000000000000000000000000000000000000000000000000000000003d200000000000000000000000000000000000000000000000000000000000003d300000000000000000000000000000000000000000000000000000000000003d400000000000000000000000000000000000000000000000000000000000003d500000000000000000000000000000000000000000000000000000000000003d600000000000000000000000000000000000000000000000000000000000003d700000000000000000000000000000000000000000000000000000000000003d800000000000000000000000000000000000000000000000000000000000003d900000000000000000000000000000000000000000000000000000000000003da00000000000000000000000000000000000000000000000000000000000003db00000000000000000000000000000000000000000000000000000000000003dc00000000000000000000000000000000000000000000000000000000000003dd00000000000000000000000000000000000000000000000000000000000003de00000000000000000000000000000000000000000000000000000000000003df00000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003e100000000000000000000000000000000000000000000000000000000000003e200000000000000000000000000000000000000000000000000000000000003e300000000000000000000000000000000000000000000000000000000000003e400000000000000000000000000000000000000000000000000000000000003e500000000000000000000000000000000000000000000000000000000000003e600000000000000000000000000000000000000000000000000000000000003e700000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000003e900000000000000000000000000000000000000000000000000000000000003ea00000000000000000000000000000000000000000000000000000000000003eb00000000000000000000000000000000000000000000000000000000000003ec00000000000000000000000000000000000000000000000000000000000003ed00000000000000000000000000000000000000000000000000000000000003ee00000000000000000000000000000000000000000000000000000000000003ef00000000000000000000000000000000000000000000000000000000000003f000000000000000000000000000000000000000000000000000000000000003f100000000000000000000000000000000000000000000000000000000000003f200000000000000000000000000000000000000000000000000000000000003f300000000000000000000000000000000000000000000000000000000000003f400000000000000000000000000000000000000000000000000000000000003f500000000000000000000000000000000000000000000000000000000000003f600000000000000000000000000000000000000000000000000000000000003f700000000000000000000000000000000000000000000000000000000000003f800000000000000000000000000000000000000000000000000000000000003f900000000000000000000000000000000000000000000000000000000000003fa00000000000000000000000000000000000000000000000000000000000003fb00000000000000000000000000000000000000000000000000000000000003fc00000000000000000000000000000000000000000000000000000000000003fd00000000000000000000000000000000000000000000000000000000000003fe0200000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000004c12000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000000000000000000000000000000000000000006ca00000000000000000000000000000000000000000000000000000000000006c100000000000000000000000000000000000000000000000000000000000006cb00000000000000000000000000000000000000000000000000000000000006c200000000000000000000000000000000000000000000000000000000000006cc00000000000000000000000000000000000000000000000000000000000006c300000000000000000000000000000000000000000000000000000000000006cd00000000000000000000000000000000000000000000000000000000000006c400000000000000000000000000000000000000000000000000000000000006ce00000000000000000000000000000000000000000000000000000000000006c500000000000000000000000000000000000000000000000000000000000006cf00000000000000000000000000000000000000000000000000000000000006c600000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000006c700000000000000000000000000000000000000000000000000000000000006d100000000000000000000000000000000000000000000000000000000000006c800000000000000000000000000000000000000000000000000000000000006d200000000000000000000000000000000000000000000000000000000000006c900000000000000000000000000000000000000000000000000000000000006d300000000000000000000000000000000000000000000000000000000000006ca00000000000000000000000000000000000000000000000000000000000006d400000000000000000000000000000000000000000000000000000000000006cb00000000000000000000000000000000000000000000000000000000000006d500000000000000000000000000000000000000000000000000000000000006cc00000000000000000000000000000000000000000000000000000000000006d600000000000000000000000000000000000000000000000000000000000006cd00000000000000000000000000000000000000000000000000000000000006d700000000000000000000000000000000000000000000000000000000000006ce00000000000000000000000000000000000000000000000000000000000006d800000000000000000000000000000000000000000000000000000000000006cf00000000000000000000000000000000000000000000000000000000000006d900000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000006da00000000000000000000000000000000000000000000000000000000000006d100000000000000000000000000000000000000000000000000000000000006db00000000000000000000000000000000000000000000000000000000000006d200000000000000000000000000000000000000000000000000000000000006dc00000000000000000000000000000000000000000000000000000000000006d300000000000000000000000000000000000000000000000000000000000006dd00000000000000000000000000000000000000000000000000000000000006d400000000000000000000000000000000000000000000000000000000000006de00000000000000000000000000000000000000000000000000000000000006d500000000000000000000000000000000000000000000000000000000000006df00000000000000000000000000000000000000000000000000000000000006d600000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000006d700000000000000000000000000000000000000000000000000000000000006e100000000000000000000000000000000000000000000000000000000000006d800000000000000000000000000000000000000000000000000000000000006e200000000000000000000000000000000000000000000000000000000000006d900000000000000000000000000000000000000000000000000000000000006e300000000000000000000000000000000000000000000000000000000000006da00000000000000000000000000000000000000000000000000000000000006e400000000000000000000000000000000000000000000000000000000000006db00000000000000000000000000000000000000000000000000000000000006e500000000000000000000000000000000000000000000000000000000000006dc00000000000000000000000000000000000000000000000000000000000006e600000000000000000000000000000000000000000000000000000000000006dd00000000000000000000000000000000000000000000000000000000000006e700000000000000000000000000000000000000000000000000000000000006de00000000000000000000000000000000000000000000000000000000000006e800000000000000000000000000000000000000000000000000000000000006df00000000000000000000000000000000000000000000000000000000000006e9000000000000000000400000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030100000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000003050000000000000000000000000000000000000000000000000000000000000306000000000000000000000000000000000000000000000000000000000000030700000000000000000000000000000000000000000000000000000000000003080000000000000000000000000000000000000000000000000000000000000309000000000000000000000000000000000000000000000000000000000000030a000000000000000000000000000000000000000000000000000000000000030b000000000000000000000000000000000000000000000000000000000000030c000000000000000000000000000000000000000000000000000000000000030d000000000000000000000000000000000000000000000000000000000000030e000000000000000000000000000000000000000000000000000000000000030f0000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000031100000000000000000000000000000000000000000000000000000000000003120000000000000000000000000000000000000000000000000000000000000313000000000000000000000000000000000000000000000000000000000000031400000000000000000000000000000000000000000000000000000000000003150000000000000000000000000000000000000000000000000000000000000316000000000000000000000000000000000000000000000000000000000000031700000000000000000000000000000000000000000000000000000000000003180000000000000000000000000000000000000000000000000000000000000319000000000000000000000000000000000000000000000000000000000000031a000000000000000000000000000000000000000000000000000000000000031b000000000000000000000000000000000000000000000000000000000000031c000000000000000000000000000000000000000000000000000000000000031d000000000000000000000000000000000000000000000000000000000000031e000000000000000000000000000000000000000000000000000000000000031f0000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032100000000000000000000000000000000000000000000000000000000000003220000000000000000000000000000000000000000000000000000000000000323000000000000000000000000000000000000000000000000000000000000032400000000000000000000000000000000000000000000000000000000000003250000000000000000000000000000000000000000000000000000000000000326000000000000000000000000000000000000000000000000000000000000032700000000000000000000000000000000000000000000000000000000000003280000000000000000000000000000000000000000000000000000000000000329000000000000000000000000000000000000000000000000000000000000032a000000000000000000000000000000000000000000000000000000000000032b000000000000000000000000000000000000000000000000000000000000032c000000000000000000000000000000000000000000000000000000000000032d000000000000000000000000000000000000000000000000000000000000032e000000000000000000000000000000000000000000000000000000000000032f0000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033100000000000000000000000000000000000000000000000000000000000003320000000000000000000000000000000000000000000000000000000000000333000000000000000000000000000000000000000000000000000000000000033400000000000000000000000000000000000000000000000000000000000003350000000000000000000000000000000000000000000000000000000000000336000000000000000000000000000000000000000000000000000000000000033700000000000000000000000000000000000000000000000000000000000003380000000000000000000000000000000000000000000000000000000000000339000000000000000000000000000000000000000000000000000000000000033a000000000000000000000000000000000000000000000000000000000000033b000000000000000000000000000000000000000000000000000000000000033c000000000000000000000000000000000000000000000000000000000000033d000000000000000000000000000000000000000000000000000000000000033e000000000000000000000000000000000000000000000000000000000000033f3f0000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040100000000000000000000000000000000000000000000000000000000000004020000000000000000000000000000000000000000000000000000000000000403000000000000000000000000000000000000000000000000000000000000040400000000000000000000000000000000000000000000000000000000000004050000000000000000000000000000000000000000000000000000000000000406000000000000000000000000000000000000000000000000000000000000040700000000000000000000000000000000000000000000000000000000000004080000000000000000000000000000000000000000000000000000000000000409000000000000000000000000000000000000000000000000000000000000040a000000000000000000000000000000000000000000000000000000000000040b000000000000000000000000000000000000000000000000000000000000040c000000000000000000000000000000000000000000000000000000000000040d000000000000000000000000000000000000000000000000000000000000040e000000000000000000000000000000000000000000000000000000000000040f0000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000041100000000000000000000000000000000000000000000000000000000000004120000000000000000000000000000000000000000000000000000000000000413000000000000000000000000000000000000000000000000000000000000041400000000000000000000000000000000000000000000000000000000000004150000000000000000000000000000000000000000000000000000000000000416000000000000000000000000000000000000000000000000000000000000041700000000000000000000000000000000000000000000000000000000000004180000000000000000000000000000000000000000000000000000000000000419000000000000000000000000000000000000000000000000000000000000041a000000000000000000000000000000000000000000000000000000000000041b000000000000000000000000000000000000000000000000000000000000041c000000000000000000000000000000000000000000000000000000000000041d000000000000000000000000000000000000000000000000000000000000041e000000000000000000000000000000000000000000000000000000000000041f0000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000042100000000000000000000000000000000000000000000000000000000000004220000000000000000000000000000000000000000000000000000000000000423000000000000000000000000000000000000000000000000000000000000042400000000000000000000000000000000000000000000000000000000000004250000000000000000000000000000000000000000000000000000000000000426000000000000000000000000000000000000000000000000000000000000042700000000000000000000000000000000000000000000000000000000000004280000000000000000000000000000000000000000000000000000000000000429000000000000000000000000000000000000000000000000000000000000042a000000000000000000000000000000000000000000000000000000000000042b000000000000000000000000000000000000000000000000000000000000042c000000000000000000000000000000000000000000000000000000000000042d000000000000000000000000000000000000000000000000000000000000042e000000000000000000000000000000000000000000000000000000000000042f0000000000000000000000000000000000000000000000000000000000000430000000000000000000000000000000000000000000000000000000000000043100000000000000000000000000000000000000000000000000000000000004320000000000000000000000000000000000000000000000000000000000000433000000000000000000000000000000000000000000000000000000000000043400000000000000000000000000000000000000000000000000000000000004350000000000000000000000000000000000000000000000000000000000000436000000000000000000000000000000000000000000000000000000000000043700000000000000000000000000000000000000000000000000000000000004380000000000000000000000000000000000000000000000000000000000000439000000000000000000000000000000000000000000000000000000000000043a000000000000000000000000000000000000000000000000000000000000043b000000000000000000000000000000000000000000000000000000000000043c000000000000000000000000000000000000000000000000000000000000043d000000000000000000000000000000000000000000000000000000000000043e0200000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000501200000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000070a0000000000000000000000000000000000000000000000000000000000000701000000000000000000000000000000000000000000000000000000000000070b0000000000000000000000000000000000000000000000000000000000000702000000000000000000000000000000000000000000000000000000000000070c0000000000000000000000000000000000000000000000000000000000000703000000000000000000000000000000000000000000000000000000000000070d0000000000000000000000000000000000000000000000000000000000000704000000000000000000000000000000000000000000000000000000000000070e0000000000000000000000000000000000000000000000000000000000000705000000000000000000000000000000000000000000000000000000000000070f00000000000000000000000000000000000000000000000000000000000007060000000000000000000000000000000000000000000000000000000000000710000000000000000000000000000000000000000000000000000000000000070700000000000000000000000000000000000000000000000000000000000007110000000000000000000000000000000000000000000000000000000000000708000000000000000000000000000000000000000000000000000000000000071200000000000000000000000000000000000000000000000000000000000007090000000000000000000000000000000000000000000000000000000000000713000000000000000000000000000000000000000000000000000000000000070a0000000000000000000000000000000000000000000000000000000000000714000000000000000000000000000000000000000000000000000000000000070b0000000000000000000000000000000000000000000000000000000000000715000000000000000000000000000000000000000000000000000000000000070c0000000000000000000000000000000000000000000000000000000000000716000000000000000000000000000000000000000000000000000000000000070d0000000000000000000000000000000000000000000000000000000000000717000000000000000000000000000000000000000000000000000000000000070e0000000000000000000000000000000000000000000000000000000000000718000000000000000000000000000000000000000000000000000000000000070f00000000000000000000000000000000000000000000000000000000000007190000000000000000000000000000000000000000000000000000000000000710000000000000000000000000000000000000000000000000000000000000071a0000000000000000000000000000000000000000000000000000000000000711000000000000000000000000000000000000000000000000000000000000071b0000000000000000000000000000000000000000000000000000000000000712000000000000000000000000000000000000000000000000000000000000071c0000000000000000000000000000000000000000000000000000000000000713000000000000000000000000000000000000000000000000000000000000071d0000000000000000000000000000000000000000000000000000000000000714000000000000000000000000000000000000000000000000000000000000071e0000000000000000000000000000000000000000000000000000000000000715000000000000000000000000000000000000000000000000000000000000071f00000000000000000000000000000000000000000000000000000000000007160000000000000000000000000000000000000000000000000000000000000720000000000000000000000000000000000000000000000000000000000000071700000000000000000000000000000000000000000000000000000000000007210000000000000000000000000000000000000000000000000000000000000718000000000000000000000000000000000000000000000000000000000000072200000000000000000000000000000000000000000000000000000000000007190000000000000000000000000000000000000000000000000000000000000723000000000000000000000000000000000000000000000000000000000000071a0000000000000000000000000000000000000000000000000000000000000724000000000000000000000000000000000000000000000000000000000000071b0000000000000000000000000000000000000000000000000000000000000725000000000000000000000000000000000000000000000000000000000000071c0000000000000000000000000000000000000000000000000000000000000726000000000000000000000000000000000000000000000000000000000000071d0000000000000000000000000000000000000000000000000000000000000727000000000000000000000000000000000000000000000000000000000000071e0000000000000000000000000000000000000000000000000000000000000728000000000000000000000000000000000000000000000000000000000000071f00000000000000000000000000000000000000000000000000000000000007290000000000000000", "txsEffectsHash": "0x001f86cec051421edd80056cd49b7bf9034751ec5b14e4c120fdc4427f5bba63", "decodedHeader": { @@ -47,10 +47,10 @@ "globalVariables": { "blockNumber": 2, "chainId": 31337, - "timestamp": 1712782671, + "timestamp": 1712912131, "version": 1, - "coinbase": "0xfefb7bf9e18d6ebc9e57c5382f9b2708ad0225d5", - "feeRecipient": "0x26a12e4e18661b750e93a1b2a0ee5ab12232135ea95cf6616fae8e8d9616f169", + "coinbase": "0xcb433ad76e9fe9c41059c27d265df41d9acbf5ff", + "feeRecipient": "0x232da3781f3971d8f6cb0246fd911a893453ef41346cbc81b495f4d887f9a1e3", "gasFees": { "feePerDaGas": 0, "feePerL1Gas": 0, @@ -59,7 +59,7 @@ }, "lastArchive": { "nextAvailableLeafIndex": 2, - "root": "0x198e7398bee770978f22a61c05397f4a663b8a1068051fac5173236bfbc3c853" + "root": "0x195de7b601a7882443a8b98043c504ef921f11a94dfa17ce1f5bc4461c685877" }, "stateReference": { "l1ToL2MessageTree": { @@ -82,8 +82,8 @@ } } }, - "header": "0x198e7398bee770978f22a61c05397f4a663b8a1068051fac5173236bfbc3c853000000020000000000000000000000000000000000000000000000000000000000000002001f86cec051421edd80056cd49b7bf9034751ec5b14e4c120fdc4427f5bba6300212ff46db74e06c26240f9a92fb6fea84709380935d657361bbd5bcb89193700a5a7c9f331ce6832a69dc81873ed87de7ceeaaed2af1d595cb14ca9616eddd2e0232573b292e99cb24c082c3ef340d619341ab76aa1e9dff1ab1914963452d0000002024c6dc6d357aad01e10fe1adb877bb28b1df97375b874116e488086ca76e5f9600000200268020a622156e2beac47431b0cd70e1c81fef9a6aa3c365bfcbed9aa7301c5e000002802ecba8caa69552bb0d9bdf0d13eb328aeb6f166a1509678d9bfa9970971d69ab000001400000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000006616fd4ffefb7bf9e18d6ebc9e57c5382f9b2708ad0225d526a12e4e18661b750e93a1b2a0ee5ab12232135ea95cf6616fae8e8d9616f169000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "publicInputsHash": "0x0020765dfc22a0d3f412276926b1c45f6b5edd0101697be96bbe30938603df6d", + "header": "0x195de7b601a7882443a8b98043c504ef921f11a94dfa17ce1f5bc4461c685877000000020000000000000000000000000000000000000000000000000000000000000002001f86cec051421edd80056cd49b7bf9034751ec5b14e4c120fdc4427f5bba6300212ff46db74e06c26240f9a92fb6fea84709380935d657361bbd5bcb89193700a5a7c9f331ce6832a69dc81873ed87de7ceeaaed2af1d595cb14ca9616eddd2e0232573b292e99cb24c082c3ef340d619341ab76aa1e9dff1ab1914963452d0000002024c6dc6d357aad01e10fe1adb877bb28b1df97375b874116e488086ca76e5f9600000200268020a622156e2beac47431b0cd70e1c81fef9a6aa3c365bfcbed9aa7301c5e000002802ecba8caa69552bb0d9bdf0d13eb328aeb6f166a1509678d9bfa9970971d69ab000001400000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000006618f703cb433ad76e9fe9c41059c27d265df41d9acbf5ff232da3781f3971d8f6cb0246fd911a893453ef41346cbc81b495f4d887f9a1e3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "publicInputsHash": "0x0018e52830d20f62abe9ccc5b87f998f69f73a0947b789bed500cb90da337d39", "numTxs": 4 } } \ No newline at end of file diff --git a/noir-projects/Earthfile b/noir-projects/Earthfile index c5decbbbeabb..ccdfe81acf1a 100644 --- a/noir-projects/Earthfile +++ b/noir-projects/Earthfile @@ -1,5 +1,6 @@ VERSION 0.8 FROM ubuntu:lunar +RUN apt-get update && apt-get install -y parallel # Install nargo COPY ../noir/+nargo/nargo /usr/bin/nargo @@ -17,7 +18,6 @@ source: build: FROM +source - RUN apt-get update && apt-get install -y parallel RUN cd noir-contracts && NARGO=nargo TRANSPILER=avm-transpiler ./bootstrap.sh RUN cd noir-protocol-circuits && NARGO=nargo ./bootstrap.sh SAVE ARTIFACT aztec-nr diff --git a/noir-projects/aztec-nr/.gitrepo b/noir-projects/aztec-nr/.gitrepo index 387fc564aa01..a2e45aaf6bc8 100644 --- a/noir-projects/aztec-nr/.gitrepo +++ b/noir-projects/aztec-nr/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AztecProtocol/aztec-nr branch = master - commit = b127ade0fd8ca26319751e1c597a24761dc3c6a0 + commit = b3b3b3c175697928e729895da32681c72e08912b method = merge cmdver = 0.4.6 - parent = aefe3b36f3b1e3f0d936942a7dd4ab140f6d26b0 + parent = b8d73dd57ffae1c5b63cb4bd7364c2038af49f50 diff --git a/noir-projects/aztec-nr/authwit/src/account.nr b/noir-projects/aztec-nr/authwit/src/account.nr index 0bc16963e252..2e33c4a08237 100644 --- a/noir-projects/aztec-nr/authwit/src/account.nr +++ b/noir-projects/aztec-nr/authwit/src/account.nr @@ -70,16 +70,6 @@ impl AccountActions { } // docs:end:entrypoint - pub fn pay_init_fee(self, fee_payload: FeePayload) { - let valid_fn = self.is_valid_impl; - let mut private_context = self.context.private.unwrap(); - - let fee_hash = fee_payload.hash(); - assert(valid_fn(private_context, fee_hash)); - fee_payload.execute_calls(private_context); - private_context.capture_min_revertible_side_effect_counter(); - } - // docs:start:spend_private_authwit pub fn spend_private_authwit(self, inner_hash: Field) -> Field { let context = self.context.private.unwrap(); diff --git a/noir-projects/aztec-nr/authwit/src/auth.nr b/noir-projects/aztec-nr/authwit/src/auth.nr index 643f725e2f29..55c15acec77e 100644 --- a/noir-projects/aztec-nr/authwit/src/auth.nr +++ b/noir-projects/aztec-nr/authwit/src/auth.nr @@ -37,7 +37,7 @@ pub fn assert_current_call_valid_authwit_public( context, on_behalf_of, function_selector, - [inner_hash], + [inner_hash].as_slice(), GasOpts::default() ).deserialize_into(); assert(result == IS_VALID_SELECTOR, "Message not authorized by account"); diff --git a/noir-projects/aztec-nr/aztec/src/context.nr b/noir-projects/aztec-nr/aztec/src/context.nr index 2b546b1e4110..c7d79f2e24b6 100644 --- a/noir-projects/aztec-nr/aztec/src/context.nr +++ b/noir-projects/aztec-nr/aztec/src/context.nr @@ -7,7 +7,10 @@ mod avm_context; mod interface; mod gas; -use interface::ContextInterface; +use interface::{ + ContextInterface, PrivateCallInterface, PublicCallInterface, PrivateVoidCallInterface, + PublicVoidCallInterface, AvmCallInterface, AvmVoidCallInterface +}; use private_context::PrivateContext; use private_context::PackedReturns; use public_context::PublicContext; diff --git a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr b/noir-projects/aztec-nr/aztec/src/context/avm_context.nr index f318253d9ce5..c4a6350af39b 100644 --- a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/avm_context.nr @@ -1,3 +1,4 @@ +use crate::hash::{compute_secret_hash, compute_message_hash, compute_message_nullifier}; use dep::protocol_types::{ address::{AztecAddress, EthAddress}, constants::{L1_TO_L2_MESSAGE_LENGTH, NESTED_CALL_L2_GAS_BUFFER}, header::Header @@ -20,9 +21,6 @@ impl AvmContext { AvmContext { inputs } } - pub fn origin(self) -> AztecAddress { - origin() - } pub fn storage_address(self) -> AztecAddress { storage_address() } @@ -43,7 +41,7 @@ impl AvmContext { * Should be automatically convertible to [Field; N]. For example str works with * one char per field. Otherwise you can use CompressedString. */ - pub fn accumulate_unencrypted_logs(&mut self, event_selector: Field, log: T) { + pub fn emit_unencrypted_log(&mut self, event_selector: Field, log: T) { emit_unencrypted_log(event_selector, log); } pub fn note_hash_exists(self, note_hash: Field, leaf_index: Field) -> bool { @@ -53,12 +51,12 @@ impl AvmContext { l1_to_l2_msg_exists(msg_hash, msg_leaf_index) == 1 } - fn call_public_function_raw( + fn call_public_function_raw( self: &mut Self, gas: GasOpts, contract_address: AztecAddress, temporary_function_selector: Field, - args: [Field; ARGS_COUNT] + args: [Field] ) -> ([Field; RET_COUNT], u8) { call( gas_for_call(gas), @@ -68,12 +66,12 @@ impl AvmContext { ) } - fn static_call_public_function_raw( + fn static_call_public_function_raw( self: &mut Self, gas: GasOpts, contract_address: AztecAddress, temporary_function_selector: Field, - args: [Field; ARGS_COUNT] + args: [Field] ) -> ([Field; RET_COUNT], u8) { call_static( gas_for_call(gas), @@ -122,36 +120,43 @@ impl PublicContextInterface for AvmContext { nullifier_exists(unsiloed_nullifier, address.to_field()) == 1 } - fn push_nullifier_read_request(&mut self, nullifier: Field) { - assert(false, "'push_nullifier_read_request' not implemented!"); - } - - fn push_nullifier_non_existent_read_request(&mut self, nullifier: Field) { - assert(false, "'push_nullifier_non_existent_read_request' not implemented!"); + fn emit_unencrypted_log(&mut self, log: T) { + let event_selector = 0; + self.emit_unencrypted_log(event_selector, log); } - fn accumulate_encrypted_logs(&mut self, log: [Field; N]) { - assert(false, "'accumulate_encrypted_logs' not implemented!"); + fn push_unencrypted_log(&mut self, log_hash: Field) { + assert(false, "'push_unencrypted_log' not required for avm - use emit_unencrypted_log!"); } - fn accumulate_unencrypted_logs(&mut self, log: T) { - let event_selector = 0; - self.accumulate_unencrypted_logs(event_selector, log); - } + fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress, leaf_index: Field) { + let secret_hash = compute_secret_hash(secret); + let message_hash = compute_message_hash( + sender, + self.chain_id(), + /*recipient=*/self.this_address(), + self.version(), + content, + secret_hash + ); + let nullifier = compute_message_nullifier(message_hash, secret, leaf_index); - fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress) { - assert(false, "'consume_l1_to_l2_message' not implemented!"); + assert(!self.nullifier_exists(nullifier, self.this_address()), "L1-to-L2 message is already nullified"); + assert(self.l1_to_l2_msg_exists(message_hash, leaf_index), "Tried to consume nonexistent L1-to-L2 message"); + + // Push nullifier (and the "commitment" corresponding to this can be "empty") + self.push_new_nullifier(nullifier, 0); } fn message_portal(&mut self, recipient: EthAddress, content: Field) { send_l2_to_l1_msg(recipient, content); } - fn call_public_function( + fn call_public_function( self: &mut Self, contract_address: AztecAddress, temporary_function_selector: FunctionSelector, - args: [Field; ARGS_COUNT], + args: [Field], gas_opts: GasOpts ) -> FunctionReturns { let results = call( @@ -167,11 +172,11 @@ impl PublicContextInterface for AvmContext { FunctionReturns::new(data_to_return) } - fn static_call_public_function( + fn static_call_public_function( self: &mut Self, contract_address: AztecAddress, temporary_function_selector: FunctionSelector, - args: [Field; ARGS_COUNT], + args: [Field], gas_opts: GasOpts ) -> FunctionReturns { let (data_to_return, success): ([Field; RETURNS_COUNT], u8) = call_static( @@ -185,11 +190,11 @@ impl PublicContextInterface for AvmContext { FunctionReturns::new(data_to_return) } - fn delegate_call_public_function( + fn delegate_call_public_function( self: &mut Self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] + args: [Field] ) -> FunctionReturns { assert(false, "'delegate_call_public_function' not implemented!"); FunctionReturns::new([0; RETURNS_COUNT]) @@ -222,10 +227,6 @@ impl ContextInterface for AvmContext { fn selector(self) -> FunctionSelector { FunctionSelector::from_field(self.inputs.selector) } - fn get_header(self) -> Header { - assert(false, "'get_header' not implemented!"); - Header::empty() - } fn get_args_hash(self) -> Field { self.inputs.args_hash } @@ -247,9 +248,6 @@ fn address() -> AztecAddress {} #[oracle(avmOpcodeStorageAddress)] fn storage_address() -> AztecAddress {} -#[oracle(avmOpcodeOrigin)] -fn origin() -> AztecAddress {} - #[oracle(avmOpcodeSender)] fn sender() -> AztecAddress {} @@ -308,20 +306,20 @@ fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> u8 {} fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) {} #[oracle(avmOpcodeCall)] -fn call( +fn call( gas: [Field; 3], // gas allocation: [l1_gas, l2_gas, da_gas] address: AztecAddress, - args: [Field; ARGS_COUNT], + args: [Field], // TODO(5110): consider passing in calldata directly temporary_function_selector: Field ) -> ([Field; RET_SIZE], u8) {} // ^ return data ^ success #[oracle(avmOpcodeStaticCall)] -fn call_static( +fn call_static( gas: [Field; 3], // gas allocation: [l1_gas, l2_gas, da_gas] address: AztecAddress, - args: [Field; ARGS_COUNT], + args: [Field], // TODO(5110): consider passing in calldata directly temporary_function_selector: Field ) -> ([Field; RET_SIZE], u8) {} diff --git a/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr b/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr index 856d57a8085e..fb2f1d27f42c 100644 --- a/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr +++ b/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr @@ -1,6 +1,6 @@ use crate::context::globals::public_global_variables::PublicGlobalVariables; -use dep::protocol_types::{abis::call_context::CallContext, header::Header, traits::Empty}; +use dep::protocol_types::{abis::call_context::CallContext, abis::gas::Gas, header::Header, traits::Empty}; // PublicContextInputs are expected to be provided to each public function // docs:start:public-context-inputs @@ -23,4 +23,4 @@ impl Empty for PublicContextInputs { start_side_effect_counter: 0 as u32, } } -} \ No newline at end of file +} diff --git a/noir-projects/aztec-nr/aztec/src/context/interface.nr b/noir-projects/aztec-nr/aztec/src/context/interface.nr index 7af943c3a4a7..a076158d71da 100644 --- a/noir-projects/aztec-nr/aztec/src/context/interface.nr +++ b/noir-projects/aztec-nr/aztec/src/context/interface.nr @@ -1,5 +1,11 @@ -use dep::protocol_types::{abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}, header::Header}; +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}, header::Header, + traits::Deserialize +}; +use crate::context::private_context::PrivateContext; +use crate::context::public_context::PublicContext; +use crate::context::avm_context::AvmContext; use crate::context::gas::GasOpts; use crate::context::public_context::FunctionReturns; @@ -13,7 +19,6 @@ trait ContextInterface { fn version(self) -> Field; fn selector(self) -> FunctionSelector; fn get_args_hash(self) -> Field; - fn get_header(self) -> Header; } // TEMPORARY: This trait is to promote sharing of the current public context @@ -27,31 +32,229 @@ trait PublicContextInterface { fn fee_per_da_gas(self) -> Field; fn fee_per_l1_gas(self) -> Field; fn fee_per_l2_gas(self) -> Field; - fn push_nullifier_read_request(&mut self, nullifier: Field); - fn push_nullifier_non_existent_read_request(&mut self, nullifier: Field); fn message_portal(&mut self, recipient: EthAddress, content: Field); - fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress); - fn accumulate_encrypted_logs(&mut self, log: [Field; N]); - fn accumulate_unencrypted_logs(&mut self, log: T); - fn call_public_function( + fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress, leaf_index: Field); + fn emit_unencrypted_log(&mut self, log: T); + // TODO(1165) Merge push_unencrypted_log into emit_unencrypted_log, since oracle call + // in PublicContext will no longer be needed for extracting log hash + fn push_unencrypted_log(&mut self, log_hash: Field); + fn call_public_function( self: &mut Self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT], + args: [Field], gas_opts: GasOpts ) -> FunctionReturns; - fn static_call_public_function( + fn static_call_public_function( self: &mut Self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT], + args: [Field], gas_opts: GasOpts ) -> FunctionReturns; - fn delegate_call_public_function( + fn delegate_call_public_function( self: &mut Self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] + args: [Field] ) -> FunctionReturns; fn nullifier_exists(self, unsiloed_nullifier: Field, address: AztecAddress) -> bool; } + +struct PrivateCallInterface { + target_contract: AztecAddress, + selector: FunctionSelector, + args_hash: Field, +} + +impl PrivateCallInterface { + pub fn call(self, context: &mut PrivateContext) -> T where T: Deserialize { + let returns = context.call_private_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + false, + false + ); + let unpacked: T = returns.unpack_into(); + unpacked + } + + pub fn static_call(self, context: &mut PrivateContext) -> T where T: Deserialize { + let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false); + returns.unpack_into() + } + + pub fn delegate_call(self, context: &mut PrivateContext) -> T where T: Deserialize { + let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true); + returns.unpack_into() + } +} + +struct PrivateVoidCallInterface { + target_contract: AztecAddress, + selector: FunctionSelector, + args_hash: Field, +} + +impl PrivateVoidCallInterface { + pub fn call(self, context: &mut PrivateContext) { + context.call_private_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + false, + false + ).assert_empty(); + } + + pub fn static_call(self, context: &mut PrivateContext) { + context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false).assert_empty(); + } + + pub fn delegate_call(self, context: &mut PrivateContext) { + context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true).assert_empty(); + } +} + +struct PublicCallInterface { + target_contract: AztecAddress, + selector: FunctionSelector, + args_hash: Field, +} + +impl PublicCallInterface { + + pub fn call(self, context: &mut PublicContext) -> T where T: Deserialize { + let returns = context.call_public_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + false, + false + ); + returns.deserialize_into() + } + + pub fn static_call(self, context: &mut PublicContext) -> T where T: Deserialize { + let returns = context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false); + returns.deserialize_into() + } + + pub fn delegate_call(self, context: &mut PublicContext) -> T where T: Deserialize { + let returns = context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true); + returns.deserialize_into() + } + + pub fn enqueue(self, context: &mut PrivateContext) { + context.call_public_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + false, + false + ) + } + + pub fn static_enqueue(self, context: &mut PrivateContext) { + context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false) + } + + pub fn delegate_enqueue(self, context: &mut PrivateContext) { + context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true) + } +} + +struct PublicVoidCallInterface { + target_contract: AztecAddress, + selector: FunctionSelector, + args_hash: Field +} + +impl PublicVoidCallInterface { + pub fn call(self, context: &mut PublicContext) { + context.call_public_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + false, + false + ).assert_empty() + } + + pub fn static_call(self, context: &mut PublicContext) { + context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false).assert_empty(); + } + + pub fn delegate_call(self, context: &mut PublicContext) { + context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true).assert_empty(); + } + + pub fn enqueue(self, context: &mut PrivateContext) { + context.call_public_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + false, + false + ) + } + + pub fn static_enqueue(self, context: &mut PrivateContext) { + context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true, false) + } + + pub fn delegate_enqueue(self, context: &mut PrivateContext) { + context.call_public_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false, true) + } +} + +struct AvmCallInterface { + target_contract: AztecAddress, + selector: FunctionSelector, + args: [Field], +} + +impl AvmCallInterface { + pub fn call(self, context: &mut AvmContext, gas_opts: GasOpts) -> T where T: Deserialize { + let returns = context.call_public_function(self.target_contract, self.selector, self.args, gas_opts); + returns.deserialize_into() + } + + pub fn static_call( + self, + context: &mut AvmContext, + gas_opts: GasOpts + ) -> T where T: Deserialize { + let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, gas_opts); + returns.deserialize_into() + } + + pub fn delegate_call(self, context: &mut AvmContext) -> T where T: Deserialize { + let returns = context.delegate_call_public_function(self.target_contract, self.selector, self.args); + returns.deserialize_into() + } +} + +struct AvmVoidCallInterface { + target_contract: AztecAddress, + selector: FunctionSelector, + args: [Field], +} + +impl AvmVoidCallInterface { + pub fn call(self, context: &mut AvmContext, gas_opts: GasOpts) { + let returns = context.call_public_function(self.target_contract, self.selector, self.args, gas_opts); + returns.assert_empty() + } + + pub fn static_call(self, context: &mut AvmContext, gas_opts: GasOpts) { + let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, gas_opts); + returns.assert_empty() + } + + pub fn delegate_call(self, context: &mut AvmContext) { + let returns = context.delegate_call_public_function(self.target_contract, self.selector, self.args); + returns.assert_empty() + } +} diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 3c8398ffb614..0c744e60d32a 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -10,8 +10,9 @@ use crate::{ }; use dep::protocol_types::{ abis::{ - call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector, - max_block_number::MaxBlockNumber, nullifier_key_validation_request::NullifierKeyValidationRequest, + gas::Gas, call_context::CallContext, function_data::FunctionData, + function_selector::FunctionSelector, max_block_number::MaxBlockNumber, + nullifier_key_validation_request::NullifierKeyValidationRequest, private_call_stack_item::PrivateCallStackItem, private_circuit_public_inputs::PrivateCircuitPublicInputs, public_call_stack_item::PublicCallStackItem, @@ -24,11 +25,13 @@ use dep::protocol_types::{ MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, - MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL + MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, + MAX_ENCRYPTED_LOGS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL }, contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, grumpkin_private_key::GrumpkinPrivateKey, header::Header, - messaging::l2_to_l1_message::L2ToL1Message, utils::reader::Reader, traits::{is_empty, Deserialize, Empty} + messaging::l2_to_l1_message::L2ToL1Message, utils::reader::Reader, + traits::{is_empty, Deserialize, Empty} }; // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) @@ -63,6 +66,8 @@ struct PrivateContext { historical_header: Header, // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) + encrypted_logs_hashes: BoundedVec, + unencrypted_logs_hashes: BoundedVec, // encrypted_logs_preimages: Vec, // unencrypted_logs_preimages: Vec, @@ -98,12 +103,6 @@ impl ContextInterface for PrivateContext { self.args_hash } - // Returns the header of a block whose state is used during private execution (not the block the transaction is - // included in). - fn get_header(self) -> Header { - self.historical_header - } - fn push_new_note_hash(&mut self, note_hash: Field) { let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter }; self.new_note_hashes.push(side_effect); @@ -141,12 +140,20 @@ impl PrivateContext { public_call_stack_hashes: BoundedVec::new(), new_l2_to_l1_msgs: BoundedVec::new(), // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) + encrypted_logs_hashes: BoundedVec::new(), + unencrypted_logs_hashes: BoundedVec::new(), // encrypted_logs_preimages: Vec::new(), // unencrypted_logs_preimages: Vec::new(), nullifier_key: Option::none() } } + // Returns the header of a block whose state is used during private execution (not the block the transaction is + // included in). + fn get_header(self) -> Header { + self.historical_header + } + // Returns the header of an arbitrary block whose block number is less than or equal to the block number // of historical header. pub fn get_header_at(self, block_number: u32) -> Header { @@ -160,8 +167,6 @@ impl PrivateContext { pub fn finish(self) -> PrivateCircuitPublicInputs { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) - let encrypted_logs_hash = 0; - let unencrypted_logs_hash = 0; let encrypted_log_preimages_length = 0; let unencrypted_log_preimages_length = 0; @@ -181,14 +186,15 @@ impl PrivateContext { new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, start_side_effect_counter: self.inputs.start_side_effect_counter, end_side_effect_counter: self.side_effect_counter, - encrypted_logs_hash, - unencrypted_logs_hash, + encrypted_logs_hashes: self.encrypted_logs_hashes.storage, + unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, encrypted_log_preimages_length, unencrypted_log_preimages_length, historical_header: self.historical_header, chain_id: self.inputs.private_global_variables.chain_id, version: self.inputs.private_global_variables.version }; + priv_circuit_pub_inputs } @@ -260,15 +266,17 @@ impl PrivateContext { } // docs:end:consume_l1_to_l2_message - pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) { - let _void1 = self.inputs; - let _void2 = log; + pub fn push_encrypted_log(&mut self, log_hash: Field) { + let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter }; + self.encrypted_logs_hashes.push(side_effect); + self.side_effect_counter = self.side_effect_counter + 1; // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) } - pub fn accumulate_unencrypted_logs(&mut self, log: T) { - let _void1 = self.inputs; - let _void2 = log; + pub fn push_unencrypted_log(&mut self, log_hash: Field) { + let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter }; + self.unencrypted_logs_hashes.push(side_effect); + self.side_effect_counter = self.side_effect_counter + 1; // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) } @@ -279,7 +287,7 @@ impl PrivateContext { args: [Field; ARGS_COUNT] ) -> PackedReturns { let args_hash = hash_args_array(args); - assert(args_hash == arguments::pack_arguments(args)); + assert(args_hash == arguments::pack_arguments_array(args)); self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, false, false) } @@ -290,7 +298,7 @@ impl PrivateContext { args: [Field; ARGS_COUNT] ) -> PackedReturns { let args_hash = hash_args_array(args); - assert(args_hash == arguments::pack_arguments(args)); + assert(args_hash == arguments::pack_arguments_array(args)); self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, true, false) } @@ -301,7 +309,7 @@ impl PrivateContext { args: [Field; ARGS_COUNT] ) -> PackedReturns { let args_hash = hash_args_array(args); - assert(args_hash == arguments::pack_arguments(args)); + assert(args_hash == arguments::pack_arguments_array(args)); self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, false, true) } @@ -387,8 +395,6 @@ impl PrivateContext { ); } - // crate::oracle::debug_log::debug_log_array_with_prefix("Private call stack item", item.serialize()); - self.private_call_stack_hashes.push(item.hash()); PackedReturns::new(item.public_inputs.returns_hash) @@ -401,7 +407,7 @@ impl PrivateContext { args: [Field; ARGS_COUNT] ) { let args_hash = hash_args_array(args); - assert(args_hash == arguments::pack_arguments(args)); + assert(args_hash == arguments::pack_arguments_array(args)); self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false, false) } @@ -412,7 +418,7 @@ impl PrivateContext { args: [Field; ARGS_COUNT] ) { let args_hash = hash_args_array(args); - assert(args_hash == arguments::pack_arguments(args)); + assert(args_hash == arguments::pack_arguments_array(args)); self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, true, false) } @@ -423,7 +429,7 @@ impl PrivateContext { args: [Field; ARGS_COUNT] ) { let args_hash = hash_args_array(args); - assert(args_hash == arguments::pack_arguments(args)); + assert(args_hash == arguments::pack_arguments_array(args)); self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false, true) } @@ -490,11 +496,12 @@ impl PrivateContext { new_l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL], start_side_effect_counter: 0, end_side_effect_counter: 0, - unencrypted_logs_hash: 0, + unencrypted_logs_hashes: [SideEffect::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL], unencrypted_log_preimages_length: 0, historical_header: Header::empty(), prover_address: AztecAddress::zero(), - revert_code: 0 + revert_code: 0, + gas_left: Gas::empty() }, is_execution_request: true }; @@ -549,6 +556,8 @@ impl Empty for PrivateContext { public_call_stack_hashes : BoundedVec::new(), new_l2_to_l1_msgs : BoundedVec::new(), historical_header: Header::empty(), + encrypted_logs_hashes: BoundedVec::new(), + unencrypted_logs_hashes: BoundedVec::new(), nullifier_key: Option::none(), } } diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index af98dc9d169a..ba70631a79fc 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -5,7 +5,7 @@ use crate::{ }, messaging::process_l1_to_l2_message, oracle::{arguments, public_call::call_public_function_internal, returns}, - hash::{hash_args_array, ArgsHasher} + hash::{hash_args, ArgsHasher} }; use dep::protocol_types::{ abis::{ @@ -20,7 +20,8 @@ use dep::protocol_types::{ MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, - MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL + MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, + MAX_UNENCRYPTED_LOGS_PER_CALL }, contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, header::Header, messaging::l2_to_l1_message::L2ToL1Message, utils::reader::Reader, traits::{Deserialize, Empty} @@ -44,7 +45,7 @@ struct PublicContext { new_l2_to_l1_msgs: BoundedVec, - unencrypted_logs_hash: Field, + unencrypted_logs_hashes: BoundedVec, unencrypted_logs_preimages_length: Field, // Header of a block whose state is used during public execution. Set by sequencer to be a header of a block @@ -68,7 +69,7 @@ impl PublicContext { new_note_hashes: BoundedVec::new(), new_nullifiers: BoundedVec::new(), new_l2_to_l1_msgs: BoundedVec::new(), - unencrypted_logs_hash: 0, + unencrypted_logs_hashes: BoundedVec::new(), unencrypted_logs_preimages_length: 0, historical_header: inputs.historical_header, prover_address: AztecAddress::zero() // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) @@ -130,9 +131,22 @@ impl PublicContext { self.return_hash = returns_hasher.hash(); } + // Keep private or ask the AVM team if you want to change it. + fn push_nullifier_read_request(&mut self, nullifier: Field) { + let request = ReadRequest { value: nullifier, counter: self.side_effect_counter }; + self.nullifier_read_requests.push(request); + self.side_effect_counter = self.side_effect_counter + 1; + } + + // Keep private or ask the AVM team if you want to change it. + fn push_nullifier_non_existent_read_request(&mut self, nullifier: Field) { + let request = ReadRequest { value: nullifier, counter: self.side_effect_counter }; + self.nullifier_non_existent_read_requests.push(request); + self.side_effect_counter = self.side_effect_counter + 1; + } + pub fn finish(self) -> PublicCircuitPublicInputs { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) - let unencrypted_logs_hash = 0; let unencrypted_log_preimages_length = 0; // Compute the public call stack hashes @@ -150,11 +164,12 @@ impl PublicContext { new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, start_side_effect_counter: self.inputs.start_side_effect_counter, end_side_effect_counter: self.side_effect_counter, - unencrypted_logs_hash, + unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, unencrypted_log_preimages_length, historical_header: self.inputs.historical_header, prover_address: self.prover_address, - revert_code: 0 + revert_code: 0, + gas_left: self.inputs.call_context.gas_left }; pub_circuit_pub_inputs } @@ -189,10 +204,6 @@ impl ContextInterface for PublicContext { self.args_hash } - fn get_header(self) -> Header { - self.historical_header - } - fn push_new_note_hash(&mut self, note_hash: Field) { let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter }; self.new_note_hashes.push(side_effect); @@ -245,18 +256,6 @@ impl PublicContextInterface for PublicContext { nullifier_exists_oracle(siloed_nullifier) == 1 } - fn push_nullifier_read_request(&mut self, nullifier: Field) { - let request = ReadRequest { value: nullifier, counter: self.side_effect_counter }; - self.nullifier_read_requests.push(request); - self.side_effect_counter = self.side_effect_counter + 1; - } - - fn push_nullifier_non_existent_read_request(&mut self, nullifier: Field) { - let request = ReadRequest { value: nullifier, counter: self.side_effect_counter }; - self.nullifier_non_existent_read_requests.push(request); - self.side_effect_counter = self.side_effect_counter + 1; - } - fn message_portal(&mut self, recipient: EthAddress, content: Field) { let message = L2ToL1Message { recipient, content }; self.new_l2_to_l1_msgs.push(message); @@ -264,7 +263,8 @@ impl PublicContextInterface for PublicContext { // We can consume message with a secret in public context because the message cannot be modified and therefore // there is no front-running risk (e.g. somebody could front run you to claim your tokens to your address). - fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress) { + // Leaf index is not used in public context, but it is used in the AVMContext which will replace it. + fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress, _leaf_index: Field) { let this = (*self).this_address(); let nullifier = process_l1_to_l2_message( self.historical_header.state.l1_to_l2_message_tree.root, @@ -280,49 +280,52 @@ impl PublicContextInterface for PublicContext { self.push_new_nullifier(nullifier, 0) } - fn accumulate_encrypted_logs(&mut self, log: [Field; N]) { + fn emit_unencrypted_log(&mut self, log: T) { let _void1 = self; let _void2 = log; // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) + // Once we hash inside circuits, this replaces push_unencrypted_log + // For now we need an oracle to get the hash } - fn accumulate_unencrypted_logs(&mut self, log: T) { - let _void1 = self; - let _void2 = log; + fn push_unencrypted_log(&mut self, log_hash: Field) { + let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter }; + self.unencrypted_logs_hashes.push(side_effect); + self.side_effect_counter = self.side_effect_counter + 1; // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) } - fn call_public_function( + fn call_public_function( self: &mut Self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT], + args: [Field], _gas: GasOpts ) -> FunctionReturns { - let args_hash = hash_args_array(args); + let args_hash = hash_args(args); assert(args_hash == arguments::pack_arguments(args)); self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false, false) } - fn static_call_public_function( + fn static_call_public_function( self: &mut Self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT], + args: [Field], _gas: GasOpts ) -> FunctionReturns { - let args_hash = hash_args_array(args); + let args_hash = hash_args(args); assert(args_hash == arguments::pack_arguments(args)); self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, true, false) } - fn delegate_call_public_function( + fn delegate_call_public_function( self: &mut Self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] + args: [Field] ) -> FunctionReturns { - let args_hash = hash_args_array(args); + let args_hash = hash_args(args); assert(args_hash == arguments::pack_arguments(args)); self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false, true) } @@ -343,7 +346,7 @@ impl Empty for PublicContext { new_note_hashes: BoundedVec::new(), new_nullifiers: BoundedVec::new(), new_l2_to_l1_msgs: BoundedVec::new(), - unencrypted_logs_hash: 0, + unencrypted_logs_hashes: BoundedVec::new(), unencrypted_logs_preimages_length: 0, historical_header: Header::empty(), prover_address: AztecAddress::zero(), diff --git a/noir-projects/aztec-nr/aztec/src/log.nr b/noir-projects/aztec-nr/aztec/src/log.nr index 033db50e09d5..0334f1407a77 100644 --- a/noir-projects/aztec-nr/aztec/src/log.nr +++ b/noir-projects/aztec-nr/aztec/src/log.nr @@ -10,21 +10,21 @@ pub fn emit_encrypted_log( encryption_pub_key: GrumpkinPoint, log: [Field; N] ) { - let _ = oracle::logs::emit_encrypted_log( + let log_hash = oracle::logs::emit_encrypted_log( contract_address, storage_slot, note_type_id, encryption_pub_key, log ); - context.accumulate_encrypted_logs(log); + context.push_encrypted_log(log_hash); } pub fn emit_unencrypted_log(context: &mut PublicContext, log: T) { let contract_address = context.this_address(); let event_selector = 5; // TODO: compute actual event selector. - let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log); - // context.accumulate_unencrypted_logs(log); + let log_hash = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log); + context.push_unencrypted_log(log_hash); } // TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy. @@ -34,6 +34,7 @@ pub fn emit_unencrypted_log(context: &mut PublicContext, log: T) { pub fn emit_unencrypted_log_from_private(context: &mut PrivateContext, log: T) { let contract_address = context.this_address(); let event_selector = 5; // TODO: compute actual event selector. - let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log); + let log_hash = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log); + context.push_unencrypted_log(log_hash); // context.accumulate_unencrypted_logs(log); } diff --git a/noir-projects/aztec-nr/aztec/src/note.nr b/noir-projects/aztec-nr/aztec/src/note.nr index b457a126b2db..6479366face8 100644 --- a/noir-projects/aztec-nr/aztec/src/note.nr +++ b/noir-projects/aztec-nr/aztec/src/note.nr @@ -1,3 +1,4 @@ +mod constants; mod lifecycle; mod note_getter; mod note_getter_options; diff --git a/noir-projects/aztec-nr/aztec/src/note/constants.nr b/noir-projects/aztec-nr/aztec/src/note/constants.nr new file mode 100644 index 000000000000..66a404c1b3d7 --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/note/constants.nr @@ -0,0 +1,6 @@ +global MAX_NOTE_FIELDS_LENGTH: u64 = 20; +// The plus 1 is 1 extra field for nonce. +// + 2 for EXTRA_DATA: [number_of_return_notes, contract_address] +global GET_NOTE_ORACLE_RETURN_LENGTH: u64 = MAX_NOTE_FIELDS_LENGTH + 1 + 2; +global MAX_NOTES_PER_PAGE: u64 = 10; +global VIEW_NOTE_ORACLE_RETURN_LENGTH: u64 = MAX_NOTES_PER_PAGE * (MAX_NOTE_FIELDS_LENGTH + 1) + 2; \ No newline at end of file diff --git a/noir-projects/aztec-nr/aztec/src/note/note_getter.nr b/noir-projects/aztec-nr/aztec/src/note/note_getter.nr index 2829583ccabf..21fa5ad15306 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_getter.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_getter.nr @@ -1,11 +1,7 @@ -use dep::protocol_types::{ - constants::{ - MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, GET_NOTE_ORACLE_RETURN_LENGTH, GET_NOTES_ORACLE_RETURN_LENGTH, - MAX_NOTES_PER_PAGE, VIEW_NOTE_ORACLE_RETURN_LENGTH -} -}; +use dep::protocol_types::{constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, GET_NOTES_ORACLE_RETURN_LENGTH}}; use crate::context::PrivateContext; use crate::note::{ + constants::{GET_NOTE_ORACLE_RETURN_LENGTH, MAX_NOTES_PER_PAGE, VIEW_NOTE_ORACLE_RETURN_LENGTH}, note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus, PropertySelector}, note_interface::NoteInterface, note_viewer_options::NoteViewerOptions, utils::compute_note_hash_for_consumption diff --git a/noir-projects/aztec-nr/aztec/src/note/note_viewer_options.nr b/noir-projects/aztec-nr/aztec/src/note/note_viewer_options.nr index eeed1ddac84e..c2bd2002cca5 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_viewer_options.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_viewer_options.nr @@ -1,7 +1,8 @@ use dep::std::option::Option; use crate::note::note_getter_options::{PropertySelector, Select, Sort, Comparator, NoteStatus}; -use dep::protocol_types::{constants::MAX_NOTES_PER_PAGE, traits::ToField}; +use dep::protocol_types::traits::ToField; use crate::note::note_interface::NoteInterface; +use crate::note::constants::MAX_NOTES_PER_PAGE; // docs:start:NoteViewerOptions struct NoteViewerOptions { diff --git a/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr b/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr index f1de424f8406..2bbf2337117d 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr @@ -1,11 +1,24 @@ +#[oracle(packArgumentsArray)] +fn pack_arguments_array_oracle(_args: [Field; N]) -> Field {} + #[oracle(packArguments)] -fn pack_arguments_oracle(_args: [Field; N]) -> Field {} +fn pack_arguments_oracle(_args: [Field]) -> Field {} + +/// - Pack arguments (array version) will notify the simulator that these arguments will be used later at +/// some point in the call. +/// - When the external call is made later, the simulator will know what the values unpack to. +/// - This oracle will not be required in public vm functions, as the vm will keep track of arguments +/// itself. +unconstrained pub fn pack_arguments_array(args: [Field; N]) -> Field { + pack_arguments_array_oracle(args) +} -/// - Pack arguments will notify the simulator that these arguments will be used later at +/// - Pack arguments (slice version) will notify the simulator that these arguments will be used later at /// some point in the call. /// - When the external call is made later, the simulator will know what the values unpack to. /// - This oracle will not be required in public vm functions, as the vm will keep track of arguments /// itself. -unconstrained pub fn pack_arguments(args: [Field; N]) -> Field { +unconstrained pub fn pack_arguments(args: [Field]) -> Field { pack_arguments_oracle(args) } + diff --git a/noir-projects/aztec-nr/aztec/src/oracle/create_commitment.nr b/noir-projects/aztec-nr/aztec/src/oracle/create_commitment.nr deleted file mode 100644 index 62c848c1d714..000000000000 --- a/noir-projects/aztec-nr/aztec/src/oracle/create_commitment.nr +++ /dev/null @@ -1,6 +0,0 @@ -#[oracle(createCommitment)] -fn create_commitment_oracle(_commitment: Field) -> Field {} - -unconstrained pub fn create_commitment(commitment: Field) { - assert(create_commitment_oracle(commitment) == 0); -} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_l1_to_l2_membership_witness.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_l1_to_l2_membership_witness.nr index e1f61401b178..55adcae73a19 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_l1_to_l2_membership_witness.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_l1_to_l2_membership_witness.nr @@ -1,4 +1,6 @@ -use dep::protocol_types::{address::AztecAddress, constants::L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH}; +use dep::protocol_types::{address::AztecAddress}; + +global L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH: u64 = 17; // Obtains membership witness (index and sibling path) for a message in the L1 to L2 message tree. #[oracle(getL1ToL2MembershipWitness)] diff --git a/noir-projects/aztec-nr/aztec/src/public_storage.nr b/noir-projects/aztec-nr/aztec/src/public_storage.nr index 7375ab91e5ad..d46b2c5ffca9 100644 --- a/noir-projects/aztec-nr/aztec/src/public_storage.nr +++ b/noir-projects/aztec-nr/aztec/src/public_storage.nr @@ -61,8 +61,12 @@ mod tests { #[test] fn test_write() { - // Here we'd want to test that what is written to storage is deserialized to the same struct, but the current - // oracle mocks lack these capabilities. - // TODO: implement this once https://github.com/noir-lang/noir/issues/4652 is closed + let slot = 7; + let to_write = TestStruct { a: 13, b: 42 }; + + let mock = OracleMock::mock("storageWrite").returns([0; 2]); // The return value is unused + + public_storage::write(slot, to_write); + assert_eq(mock.get_last_params(), (slot, to_write.serialize())); } } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr index b72b405d1976..c48e9b3708f9 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr @@ -1,9 +1,10 @@ use dep::protocol_types::{ - constants::{MAX_NOTES_PER_PAGE, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL}, + constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, abis::side_effect::{SideEffect, SideEffectLinkedToNoteHash} }; use crate::context::{PrivateContext, PublicContext, Context}; use crate::note::{ + constants::MAX_NOTES_PER_PAGE, lifecycle::{create_note, create_note_hash_from_public, destroy_note}, note_getter::{get_notes, view_notes}, note_getter_options::NoteGetterOptions, note_header::NoteHeader, note_interface::NoteInterface, note_viewer_options::NoteViewerOptions, diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable.nr index fa61113bc78e..533639390d82 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable.nr @@ -1,4 +1,6 @@ mod shared_mutable; mod scheduled_value_change; +mod shared_mutable_private_getter; use shared_mutable::SharedMutable; +use shared_mutable_private_getter::SharedMutablePrivateGetter; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr index 63e3a9c05c3a..5d327b1f25b4 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr @@ -155,7 +155,7 @@ mod test { #[test] fn test_get_current_value_in_public_after_change() { - let (state_var, block_number ) = setup(false); + let (state_var, block_number) = setup(false); let slot = state_var.get_derived_storage_slot(); let (pre, post) = (13, 17); @@ -172,16 +172,54 @@ mod test { let slot = state_var.get_derived_storage_slot(); let (pre, post) = (13, 17); + // Change in the future + OracleMock::mock("storageRead").with_params((slot, 3)).returns([pre, post, block_number + 1]); + + let write_mock = OracleMock::mock("storageWrite").returns([0; 3]); // The oracle return value is actually unused + + let new_value = 42; + state_var.schedule_value_change(new_value); + + // The new scheduled change replaces the old one + assert_eq(write_mock.get_last_params(), (slot, [pre, new_value, block_number + TEST_DELAY])); + } + + #[test] + fn test_schedule_value_change_at_change() { + let (state_var, block_number) = setup(false); + let slot = state_var.get_derived_storage_slot(); + let (pre, post) = (13, 17); - OracleMock::mock("storageRead").with_params((slot, 3)).returns([pre, post, block_number + 1]); + // Change in the current block + OracleMock::mock("storageRead").with_params((slot, 3)).returns([pre, post, block_number]); + + let write_mock = OracleMock::mock("storageWrite").returns([0; 3]); // The oracle return value is actually unused + + let new_value = 42; + state_var.schedule_value_change(new_value); + + // The previous 'post' value is the current one and becomes the 'pre' value + assert_eq(write_mock.get_last_params(), (slot, [post, new_value, block_number + TEST_DELAY])); + } + + #[test] + fn test_schedule_value_change_after_change() { + let (state_var, block_number) = setup(false); + + let slot = state_var.get_derived_storage_slot(); + let (pre, post) = (13, 17); + + // Change in the past + OracleMock::mock("storageRead").with_params((slot, 3)).returns([pre, post, block_number - 1]); + + let write_mock = OracleMock::mock("storageWrite").returns([0; 3]); // The oracle return value is actually unused let new_value = 42; - // Here we want to assert that the `storageWrite` oracle is called with a certain set of values, but the current - // oracle mocks don't have those capabilities. - // TODO: implement this once https://github.com/noir-lang/noir/issues/4652 is closed - // OracleMock::mock("storageWrite").expect_call((slot, [pre, new_value, block_number + DELAY])); - // state_var.schedule_value_change(new_value); + state_var.schedule_value_change(new_value); + + // The previous 'post' value is the current one and becomes the 'pre' value + assert_eq(write_mock.get_last_params(), (slot, [post, new_value, block_number + TEST_DELAY])); } #[test] diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable_private_getter.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable_private_getter.nr new file mode 100644 index 000000000000..2f4f4339481d --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable_private_getter.nr @@ -0,0 +1,70 @@ +use dep::protocol_types::{hash::pedersen_hash, traits::FromField, address::AztecAddress}; + +use crate::context::{PrivateContext, Context}; +use crate::history::public_storage::public_storage_historical_read; +use crate::public_storage; +use crate::state_vars::{storage::Storage, shared_mutable::scheduled_value_change::ScheduledValueChange}; + +struct SharedMutablePrivateGetter { + context: PrivateContext, + // The contract address of the contract we want to read from + other_contract_address: AztecAddress, + // The storage slot where the SharedMutable is stored on the other contract + storage_slot: Field, +} + +// We have this as a view-only interface to reading Shared Mutables in other contracts. +// Currently the Shared Mutable does not support this. We can adapt SharedMutable at a later date +impl SharedMutablePrivateGetter { + pub fn new( + context: PrivateContext, + other_contract_address: AztecAddress, + storage_slot: Field, + ) -> Self { + assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); + assert(other_contract_address.to_field() != 0, "Other contract address cannot be 0"); + Self { context, other_contract_address, storage_slot } + } + + pub fn get_current_value_in_private(self) -> T where T: FromField { + let mut context = self.context; + + let (scheduled_value_change, historical_block_number) = self.historical_read_from_public_storage(context); + let block_horizon = scheduled_value_change.get_block_horizon(historical_block_number); + + // We prevent this transaction from being included in any block after the block horizon, ensuring that the + // historical public value matches the current one, since it can only change after the horizon. + context.set_tx_max_block_number(block_horizon); + scheduled_value_change.get_current_at(historical_block_number) + } + + fn historical_read_from_public_storage( + self, + context: PrivateContext + ) -> (ScheduledValueChange, u32) where T: FromField { + let derived_slot = self.get_derived_storage_slot(); + + // Ideally the following would be simply public_storage::read_historical, but we can't implement that yet. + let mut raw_fields = [0; 3]; + for i in 0..3 { + raw_fields[i] = public_storage_historical_read( + context, + derived_slot + i as Field, + self.other_contract_address + ); + } + + let scheduled_value: ScheduledValueChange = ScheduledValueChange::deserialize(raw_fields); + let historical_block_number = context.historical_header.global_variables.block_number as u32; + + (scheduled_value, historical_block_number) + } + + fn get_derived_storage_slot(self) -> Field { + // Since we're actually storing three values (a ScheduledValueChange struct), we hash the storage slot to get a + // unique location in which we can safely store as much data as we need. This could be removed if we informed + // the slot allocator of how much space we need so that proper padding could be added. + // See https://github.com/AztecProtocol/aztec-packages/issues/5492 + pedersen_hash([self.storage_slot, 0], 0) + } +} diff --git a/noir-projects/noir-contracts/Nargo.toml b/noir-projects/noir-contracts/Nargo.toml index 73e8bb9295e9..b3d1c57c7526 100644 --- a/noir-projects/noir-contracts/Nargo.toml +++ b/noir-projects/noir-contracts/Nargo.toml @@ -24,6 +24,7 @@ members = [ "contracts/escrow_contract", "contracts/gas_token_contract", "contracts/import_test_contract", + "contracts/key_registry_contract", "contracts/inclusion_proofs_contract", "contracts/lending_contract", "contracts/parent_contract", diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/app_subscription_contract/Nargo.toml index 34df286511ba..cf460fd94978 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/Nargo.toml @@ -7,3 +7,5 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } authwit = { path = "../../../aztec-nr/authwit" } +gas_token = { path = "../gas_token_contract" } +token = { path = "../token_contract" } \ No newline at end of file diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr index 999f07771bd0..eb316f301867 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr @@ -17,6 +17,9 @@ contract AppSubscription { use crate::subscription_note::{SubscriptionNote, SUBSCRIPTION_NOTE_LEN}; + use dep::gas_token::GasToken; + use dep::token::Token; + #[aztec(storage)] struct Storage { // The following is only needed in private but we use ShareImmutable here instead of PrivateImmutable because @@ -44,19 +47,11 @@ contract AppSubscription { note.remaining_txs -= 1; storage.subscriptions.at(user_address).replace(&mut note, true); - context.call_public_function( - storage.gas_token_address.read_private(), - FunctionSelector::from_signature("pay_fee(Field)"), - [42] - ); + GasToken::at(storage.gas_token_address.read_private()).pay_fee(42).enqueue(&mut context); context.capture_min_revertible_side_effect_counter(); - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("assert_not_expired(Field)"), - [note.expiry_block_number] - ); + AppSubscription::at(context.this_address()).assert_not_expired(note.expiry_block_number).enqueue(&mut context); payload.execute_calls(&mut context, storage.target_address.read_private()); } @@ -102,20 +97,15 @@ contract AppSubscription { ) { assert(tx_count as u64 <= SUBSCRIPTION_TXS as u64); - let _ = context.call_private_function( - storage.subscription_token_address.read_private(), - FunctionSelector::from_signature("transfer((Field),(Field),Field,Field)"), - [ - context.msg_sender().to_field(), storage.subscription_recipient_address.read_private().to_field(), storage.subscription_price.read_private(), nonce - ] - ); + Token::at(storage.subscription_token_address.read_private()).transfer( + context.msg_sender(), + storage.subscription_recipient_address.read_private(), + storage.subscription_price.read_private(), + nonce + ).call(&mut context); // Assert that the given expiry_block_number < current_block_number + SUBSCRIPTION_DURATION_IN_BLOCKS. - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("assert_block_number(Field)"), - [expiry_block_number] - ); + AppSubscription::at(context.this_address()).assert_block_number(expiry_block_number).enqueue(&mut context); let mut subscription_note = SubscriptionNote::new(subscriber_address, expiry_block_number, tx_count); if (!is_initialized(subscriber_address)) { diff --git a/noir-projects/noir-contracts/contracts/avm_acvm_interop_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_acvm_interop_test_contract/src/main.nr index c1af41666e98..bece62fc8dce 100644 --- a/noir-projects/noir-contracts/contracts/avm_acvm_interop_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_acvm_interop_test_contract/src/main.nr @@ -42,7 +42,7 @@ contract AvmAcvmInteropTest { context.call_public_function( context.this_address(), FunctionSelector::from_signature("constant_field_acvm()"), - [], + [].as_slice(), GasOpts::default() ).deserialize_into() } @@ -52,14 +52,19 @@ contract AvmAcvmInteropTest { context.call_public_function( context.this_address(), FunctionSelector::from_signature("constant_field_avm()"), - [], + [].as_slice(), GasOpts::default() ).deserialize_into() } #[aztec(public-vm)] fn avm_to_acvm_call(selector: FunctionSelector, args: Field) { - context.call_public_function(context.this_address(), selector, [args], GasOpts::default()).assert_empty(); + context.call_public_function( + context.this_address(), + selector, + [args].as_slice(), + GasOpts::default() + ).assert_empty(); } /************************************************************************ diff --git a/noir-projects/noir-contracts/contracts/avm_nested_calls_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_nested_calls_test_contract/src/main.nr index 4c056f838de8..e5d34183f424 100644 --- a/noir-projects/noir-contracts/contracts/avm_nested_calls_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_nested_calls_test_contract/src/main.nr @@ -42,7 +42,7 @@ contract AvmNestedCallsTest { GasOpts::default(), context.this_address(), selector, - [arg_a, arg_b] + [arg_a, arg_b].as_slice() ); let data_to_return: [Field; 1] = results.0; // this explicit size is necessary to ensure that ret_size is compile-time @@ -71,7 +71,7 @@ contract AvmNestedCallsTest { GasOpts::new(l1_gas, l2_gas, da_gas), context.this_address(), selector, - [arg_a, arg_b] + [arg_a, arg_b].as_slice() ); let data_to_return: [Field; 1] = results.0; // this explicit size is necessary to ensure that ret_size is compile-time @@ -85,15 +85,7 @@ contract AvmNestedCallsTest { // Use the `call_public_function` wrapper to initiate a nested call to the add function #[aztec(public-vm)] fn nested_call_to_add(arg_a: Field, arg_b: Field) -> pub Field { - let selector = FunctionSelector::from_signature("add_args_return(Field,Field)"); - - // Nested call using standard context interface function - context.call_public_function( - context.this_address(), - selector, - [arg_a, arg_b], - GasOpts::default() - ).deserialize_into() + AvmNestedCallsTest::at(context.this_address()).add_args_return(arg_a, arg_b).call(&mut context, GasOpts::default()) } // Directly call_static the external call opcode to initiate a nested call to the add function @@ -105,7 +97,7 @@ contract AvmNestedCallsTest { GasOpts::default(), context.this_address(), selector, - [arg_a, arg_b] + [arg_a, arg_b].as_slice() ); (result_data[0], success) @@ -117,7 +109,12 @@ contract AvmNestedCallsTest { let selector = FunctionSelector::from_signature("set_storage_single(Field)").to_field(); let calldata: [Field; 1] = [20]; - let (_data_to_return, success): ([Field; 0], u8) = context.static_call_public_function_raw(GasOpts::default(), context.this_address(), selector, calldata); + let (_data_to_return, success): ([Field; 0], u8) = context.static_call_public_function_raw( + GasOpts::default(), + context.this_address(), + selector, + calldata.as_slice() + ); success } @@ -125,40 +122,24 @@ contract AvmNestedCallsTest { // Indirectly call_static the external call opcode to initiate a nested call to the add function #[aztec(public-vm)] fn nested_static_call_to_add(arg_a: Field, arg_b: Field) -> pub Field { - let selector = FunctionSelector::from_signature("add_args_return(Field,Field)"); - - context.static_call_public_function( - context.this_address(), - selector, - [arg_a, arg_b], - GasOpts::default() - ).deserialize_into() + AvmNestedCallsTest::at(context.this_address()).add_args_return(arg_a, arg_b).static_call(&mut context, GasOpts::default()) } // Indirectly call_static `set_storage_single`. Should revert since it's accessing storage. #[aztec(public-vm)] fn nested_static_call_to_set_storage() { - let selector = FunctionSelector::from_signature("set_storage_single(Field)"); - let calldata: [Field; 1] = [20]; - - context.static_call_public_function(context.this_address(), selector, calldata, GasOpts::default()).assert_empty(); + AvmNestedCallsTest::at(context.this_address()).set_storage_single(20).static_call(&mut context, GasOpts::default()); } #[aztec(public-vm)] fn create_same_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) { context.push_new_nullifier(nullifier, 0); - - let selector = FunctionSelector::from_signature("new_nullifier(Field)"); - let calldata: [Field; 1] = [nullifier]; - let _ : FunctionReturns<0> = context.call_public_function(nestedAddress, selector, calldata, GasOpts::default()); + AvmNestedCallsTest::at(nestedAddress).new_nullifier(nullifier).call(&mut context, GasOpts::default()); } #[aztec(public-vm)] fn create_different_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) { context.push_new_nullifier(nullifier, 0); - - let selector = FunctionSelector::from_signature("new_nullifier(Field)"); - let calldata: [Field; 1] = [nullifier + 1]; - let _ : FunctionReturns<0> = context.call_public_function(nestedAddress, selector, calldata, GasOpts::default()); + AvmNestedCallsTest::at(nestedAddress).new_nullifier(nullifier + 1).call(&mut context, GasOpts::default()); } } diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index 918ee1abb271..7eb12dd0e7c8 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -185,7 +185,7 @@ contract AvmTest { #[aztec(public-vm)] fn test_get_contract_instance() { let ci = get_contract_instance_avm(context.this_address()); - assert(ci.is_some()); + assert(ci.is_some(), "Contract instance not found!"); } /************************************************************************ @@ -206,11 +206,6 @@ contract AvmTest { context.msg_sender() } - #[aztec(public-vm)] - fn get_origin() -> pub AztecAddress { - context.origin() - } - #[aztec(public-vm)] fn get_portal() -> pub EthAddress { context.this_portal_address() @@ -258,7 +253,9 @@ contract AvmTest { #[aztec(public-vm)] fn check_selector() { - assert(context.selector() == FunctionSelector::from_signature("check_selector()")); + assert( + context.selector() == FunctionSelector::from_signature("check_selector()"), "Unexpected selector!" + ); } #[aztec(public-vm)] @@ -268,10 +265,10 @@ contract AvmTest { #[aztec(public-vm)] fn emit_unencrypted_log() { - context.accumulate_unencrypted_logs(/*event_selector=*/ 5, /*message=*/ [10, 20, 30]); - context.accumulate_unencrypted_logs(/*event_selector=*/ 8, /*message=*/ "Hello, world!"); + context.emit_unencrypted_log(/*event_selector=*/ 5, /*message=*/ [10, 20, 30]); + context.emit_unencrypted_log(/*event_selector=*/ 8, /*message=*/ "Hello, world!"); let s: CompressedString<2,44> = CompressedString::from_string("A long time ago, in a galaxy far far away..."); - context.accumulate_unencrypted_logs(/*event_selector=*/ 10, /*message=*/ s); + context.emit_unencrypted_log(/*event_selector=*/ 10, /*message=*/ s); } #[aztec(public-vm)] @@ -299,7 +296,7 @@ contract AvmTest { #[aztec(public-vm)] fn assert_nullifier_exists(nullifier: Field) { - assert(context.nullifier_exists(nullifier, context.this_address())); + assert(context.nullifier_exists(nullifier, context.this_address()), "Nullifier doesn't exist!"); } // Use the standard context interface to emit a new nullifier diff --git a/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr b/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr index 4e688ceb9876..38511fc3a9f0 100644 --- a/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/benchmarking_contract/src/main.nr @@ -44,12 +44,7 @@ contract Benchmarking { fn increment_balance(owner: AztecAddress, value: Field) { let current = storage.balances.at(owner).read(); storage.balances.at(owner).write(current + value); - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("broadcast((Field))"), - [owner.to_field()], - GasOpts::default() - ).assert_empty(); + Benchmarking::at(context.this_address()).broadcast(owner).call(&mut context); } // Emits a public log. diff --git a/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr b/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr index ccad0898f9ac..51f914b567a6 100644 --- a/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr +++ b/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr @@ -3,9 +3,10 @@ use dep::aztec::prelude::{AztecAddress, FunctionSelector, PrivateContext, NoteHe use dep::aztec::{ protocol_types::{ traits::{ToField, Serialize, FromField}, - constants::{MAX_NOTES_PER_PAGE, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL} + constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, }, - context::{PublicContext, Context}, note::note_getter::view_notes, state_vars::PrivateSet + context::{PublicContext, Context}, note::note_getter::view_notes, state_vars::PrivateSet, + note::constants::MAX_NOTES_PER_PAGE, }; use dep::std; use dep::std::{option::Option}; diff --git a/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr b/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr index 1e54f0c2866e..fb37c121fcbf 100644 --- a/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr @@ -2,12 +2,12 @@ mod cards; mod game; contract CardGame { - use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress, constants::MAX_NOTES_PER_PAGE}; + use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}; use dep::aztec::{context::Context, hash::pedersen_hash, state_vars::{Map, PublicMutable}}; use dep::value_note::{balance_utils, value_note::{ValueNote, VALUE_NOTE_LEN}}; - use dep::aztec::note::note_header::NoteHeader; + use dep::aztec::note::{note_header::NoteHeader, constants::MAX_NOTES_PER_PAGE}; use crate::cards::{PACK_CARDS, Deck, Card, get_pack_cards, compute_deck_strength}; use crate::game::{NUMBER_OF_PLAYERS, NUMBER_OF_CARDS_DECK, PLAYABLE_CARDS, PlayerEntry, Game, GAME_SERIALIZED_LEN}; @@ -39,13 +39,8 @@ contract CardGame { collection.remove_cards(cards, player); let mut game_deck = storage.game_decks.at(game as Field).at(player); let _added_to_game_deck = game_deck.add_cards(cards, player); - let selector = FunctionSelector::from_signature("on_game_joined(u32,(Field),u32)"); let strength = compute_deck_strength(cards); - context.call_public_function( - context.this_address(), - selector, - [game as Field, player.to_field(), strength] - ); + CardGame::at(context.this_address()).on_game_joined(game, player, strength as u32).enqueue(&mut context); } #[aztec(public)] @@ -75,13 +70,8 @@ contract CardGame { let mut game_deck = storage.game_decks.at(game as Field).at(player); game_deck.remove_cards([card], player); - let selector = FunctionSelector::from_signature("on_card_played(u32,(Field),Field)"); // docs:start:call_public_function - context.call_public_function( - context.this_address(), - selector, - [game as Field, player.to_field(), card.to_field()] - ); + CardGame::at(context.this_address()).on_card_played(game, player, card.to_field()).enqueue(&mut context); // docs:end:call_public_function } @@ -107,13 +97,7 @@ contract CardGame { let mut collection = storage.collections.at(player); let _inserted_cards = collection.add_cards(cards, player); - - let selector = FunctionSelector::from_signature("on_cards_claimed(u32,(Field),Field)"); - context.call_public_function( - context.this_address(), - selector, - [game as Field, player.to_field(), pedersen_hash(cards_fields, 0)] - ); + CardGame::at(context.this_address()).on_cards_claimed(game, player, pedersen_hash(cards_fields, 0)).enqueue(&mut context); } #[aztec(public)] diff --git a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr index 8304aaecb3bc..15117e2dbfa7 100644 --- a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr @@ -94,14 +94,7 @@ contract Child { #[aztec(public)] fn set_value_twice_with_nested_first() { - let pub_set_value_selector = FunctionSelector::from_signature("pub_set_value(Field)"); - let _result: Field = context.call_public_function( - context.this_address(), - pub_set_value_selector, - [10], - GasOpts::default() - ).deserialize_into(); - + let _result = Child::at(context.this_address()).pub_set_value(10).call(&mut context); storage.current_value.write(20); emit_unencrypted_log(&mut context, 20); } @@ -110,13 +103,6 @@ contract Child { fn set_value_twice_with_nested_last() { storage.current_value.write(20); emit_unencrypted_log(&mut context, 20); - - let pub_set_value_selector = FunctionSelector::from_signature("pub_set_value(Field)"); - let _result: Field = context.call_public_function( - context.this_address(), - pub_set_value_selector, - [10], - GasOpts::default() - ).deserialize_into(); + let _result = Child::at(context.this_address()).pub_set_value(10).call(&mut context); } } diff --git a/noir-projects/noir-contracts/contracts/claim_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/claim_contract/Nargo.toml index 1db74bdf3ac7..7d81995453f9 100644 --- a/noir-projects/noir-contracts/contracts/claim_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/claim_contract/Nargo.toml @@ -7,3 +7,4 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } value_note = { path = "../../../aztec-nr/value-note" } +token = { path = "../token_contract" } diff --git a/noir-projects/noir-contracts/contracts/claim_contract/src/interfaces.nr b/noir-projects/noir-contracts/contracts/claim_contract/src/interfaces.nr deleted file mode 100644 index a7e14c8d9fcb..000000000000 --- a/noir-projects/noir-contracts/contracts/claim_contract/src/interfaces.nr +++ /dev/null @@ -1,37 +0,0 @@ -use dep::aztec::{ - protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, - context::PrivateContext -}; - -struct Token { - address: AztecAddress, -} - -impl Token { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - fn mint_public(self: Self, context: &mut PrivateContext, to: AztecAddress, amount: Field) { - let _ret = context.call_public_function( - self.address, - FunctionSelector::from_signature("mint_public((Field),Field)"), - [to.to_field(), amount] - ); - } - - pub fn transfer( - self: Self, - context: &mut PrivateContext, - from: AztecAddress, - to: AztecAddress, - amount: Field, - nonce: Field - ) { - let _ret = context.call_private_function( - self.address, - FunctionSelector::from_signature("transfer((Field),(Field),Field,Field)"), - [from.to_field(), to.to_field(), amount, nonce] - ); - } -} diff --git a/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr b/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr index 6cac882ba6f9..090ea87a0a0d 100644 --- a/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr @@ -1,13 +1,11 @@ contract Claim { - mod interfaces; - use dep::aztec::{ history::note_inclusion::prove_note_inclusion, protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, state_vars::SharedImmutable }; use dep::value_note::value_note::ValueNote; - use interfaces::Token; + use dep::token::Token; #[aztec(storage)] struct Storage { @@ -43,7 +41,6 @@ contract Claim { context.push_new_nullifier(proof_note.compute_nullifier(&mut context), 0); // 4) Finally we mint the reward token to the sender of the transaction - let reward_token = Token::at(storage.reward_token.read_private()); - reward_token.mint_public(&mut context, recipient, proof_note.value); + Token::at(storage.reward_token.read_private()).mint_public(recipient, proof_note.value).enqueue(&mut context); } } diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/crowdfunding_contract/Nargo.toml index 78810768a4d4..aa72f2f65f43 100644 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/Nargo.toml @@ -7,3 +7,4 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } value_note = { path = "../../../aztec-nr/value-note" } +token = { path = "../token_contract" } diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/interfaces.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/interfaces.nr deleted file mode 100644 index 746f8e0e24cc..000000000000 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/interfaces.nr +++ /dev/null @@ -1,27 +0,0 @@ -use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}}; -use dep::aztec::{context::{PrivateContext, PublicContext}}; - -struct Token { - address: AztecAddress, -} - -impl Token { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - pub fn transfer( - self: Self, - context: &mut PrivateContext, - from: AztecAddress, - to: AztecAddress, - amount: Field, - nonce: Field - ) { - let _ret = context.call_private_function( - self.address, - FunctionSelector::from_signature("transfer((Field),(Field),Field,Field)"), - [from.to_field(), to.to_field(), amount, nonce] - ); - } -} diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr index 0729e184f8b7..b096555a40fa 100644 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr @@ -1,7 +1,6 @@ // docs:start:empty-contract contract Crowdfunding { // docs:end:empty-contract - mod interfaces; use dep::aztec::{ log::emit_unencrypted_log_from_private, @@ -9,7 +8,7 @@ contract Crowdfunding { state_vars::{PrivateSet, PublicImmutable, SharedImmutable} }; use dep::value_note::value_note::ValueNote; - use interfaces::Token; + use dep::token::Token; #[aztec(event)] struct WithdrawalProcessed { @@ -68,23 +67,17 @@ contract Crowdfunding { #[aztec(private)] fn donate(amount: u64) { // 1) Check that the deadline has not passed - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("_check_deadline()"), - [] - ); + Crowdfunding::at(context.this_address())._check_deadline().enqueue(&mut context); // docs:end:call-check-deadline // docs:start:do-transfer // 2) Transfer the donation tokens from donor to this contract - let donation_token = Token::at(storage.donation_token.read_private()); - donation_token.transfer( - &mut context, + Token::at(storage.donation_token.read_private()).transfer( context.msg_sender(), context.this_address(), amount as Field, 0 - ); + ).call(&mut context); // docs:end:do-transfer // 3) Create a value note for the donor so that he can later on claim a rewards token in the Claim @@ -102,14 +95,7 @@ contract Crowdfunding { assert(context.msg_sender() == operator_address, "Not an operator"); // 2) Transfer the donation tokens from this contract to the operator - let donation_token = Token::at(storage.donation_token.read_private()); - donation_token.transfer( - &mut context, - context.this_address(), - operator_address, - amount as Field, - 0 - ); + Token::at(storage.donation_token.read_private()).transfer(context.this_address(), operator_address, amount as Field, 0).call(&mut context); // 3) Emit an unencrypted event so that anyone can audit how much the operator has withdrawn let event = WithdrawalProcessed { amount, who: operator_address }; diff --git a/noir-projects/noir-contracts/contracts/delegator_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/delegator_contract/Nargo.toml index 8299f932ad2f..1aad229b8288 100644 --- a/noir-projects/noir-contracts/contracts/delegator_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/delegator_contract/Nargo.toml @@ -6,4 +6,5 @@ compiler_version = ">=0.25.0" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } -value_note = { path = "../../../aztec-nr/value-note" } \ No newline at end of file +value_note = { path = "../../../aztec-nr/value-note" } +delegated_on = { path = "../delegated_on_contract"} \ No newline at end of file diff --git a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr b/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr index 5cb189e74105..939c2f1907fa 100644 --- a/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/delegator_contract/src/main.nr @@ -5,6 +5,7 @@ contract Delegator { PublicMutable, PrivateSet, Deserialize }; use dep::value_note::value_note::ValueNote; + use dep::delegated_on::DelegatedOn; #[aztec(storage)] struct Storage { @@ -15,29 +16,21 @@ contract Delegator { #[aztec(private)] fn private_delegate_set_value( target_contract: AztecAddress, - target_selector: FunctionSelector, - args: [Field; 2] + value: Field, + owner: AztecAddress ) -> Field { // Call the target private function - context.delegate_call_private_function(target_contract, target_selector, args).unpack_into() + DelegatedOn::at(target_contract).private_set_value(value, owner).delegate_call(&mut context) } #[aztec(private)] - fn enqueued_delegate_set_value( - target_contract: AztecAddress, - target_selector: FunctionSelector, - args: [Field; 1] - ) { - context.delegate_call_public_function(target_contract, target_selector, args); + fn enqueued_delegate_set_value(target_contract: AztecAddress, value: Field) { + DelegatedOn::at(target_contract).public_set_value(value).delegate_enqueue(&mut context) } #[aztec(public)] - fn public_delegate_set_value( - target_contract: AztecAddress, - target_selector: FunctionSelector, - args: [Field; 1] - ) { - let _result: Field = context.delegate_call_public_function(target_contract, target_selector, args).deserialize_into(); + fn public_delegate_set_value(target_contract: AztecAddress, value: Field) -> Field { + DelegatedOn::at(target_contract).public_set_value(value).delegate_call(&mut context) } unconstrained fn view_private_value(amount: Field, owner: AztecAddress) -> pub Field { diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index ae0d5e3d40a9..4c4eb170e98b 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -115,10 +115,9 @@ contract DocsExample { // and returns the response. // Used to test that we can retrieve values through calls and // correctly return them in the simulation - context.call_private_function_no_args( - context.this_address(), - FunctionSelector::from_signature("get_shared_immutable_constrained_private()") - ).unpack_into() + let mut leader = DocsExample::at(context.this_address()).get_shared_immutable_constrained_private().call(&mut context); + leader.points += 1; + leader } #[aztec(public)] @@ -127,10 +126,9 @@ contract DocsExample { // and returns the response. // Used to test that we can retrieve values through calls and // correctly return them in the simulation - context.call_public_function_no_args( - context.this_address(), - FunctionSelector::from_signature("get_shared_immutable_constrained_public()") - ).deserialize_into() + let mut leader = DocsExample::at(context.this_address()).get_shared_immutable_constrained_public().call(&mut context); + leader.points += 1; + leader } #[aztec(public)] @@ -138,6 +136,12 @@ contract DocsExample { storage.shared_immutable.read_public() } + #[aztec(public)] + fn get_shared_immutable_constrained_public_multiple() -> pub [Leader; 5] { + let a = storage.shared_immutable.read_public(); + [a, a, a, a, a] + } + #[aztec(private)] fn get_shared_immutable_constrained_private() -> pub Leader { storage.shared_immutable.read_private() @@ -178,7 +182,7 @@ contract DocsExample { } #[aztec(private)] - fn insert_notes(amounts: [u8; 10]) { + fn insert_notes(amounts: [u8; 3]) { for i in 0..amounts.len() { let mut note = CardNote::new(amounts[i], 1, context.msg_sender()); storage.set.insert(&mut note, true); @@ -210,12 +214,7 @@ contract DocsExample { fn update_legendary_card(randomness: Field, points: u8) { let mut new_card = CardNote::new(points, randomness, context.msg_sender()); storage.legendary_card.replace(&mut new_card, true); - - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("update_leader((Field),u8)"), - [context.msg_sender().to_field(), points as Field] - ); + DocsExample::at(context.this_address()).update_leader(context.msg_sender(), points).enqueue(&mut context); } #[aztec(private)] @@ -234,11 +233,7 @@ contract DocsExample { storage.legendary_card.replace(&mut new_card, true); // docs:end:state_vars-PrivateMutableReplace - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("update_leader((Field),u8)"), - [context.msg_sender().to_field(), points as Field] - ); + DocsExample::at(context.this_address()).update_leader(context.msg_sender(), points).enqueue(&mut context); } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr index a9081073066c..1b5af4b82800 100644 --- a/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr @@ -1,7 +1,7 @@ // docs:start:easy_private_token_contract contract EasyPrivateToken { use dep::aztec::prelude::{AztecAddress, NoteHeader, Map}; - use dep::value_note::{balance_utils, value_note::ValueNote}; + use dep::value_note::balance_utils; use dep::easy_private_state::EasyPrivateUint; #[aztec(storage)] diff --git a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr index 76cc88e1201f..634acdb45bd5 100644 --- a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr @@ -30,11 +30,7 @@ contract EasyPrivateVoting { let secret = context.request_nullifier_secret_key(context.msg_sender()); // get secret key of caller of function let nullifier = dep::std::hash::pedersen_hash([context.msg_sender().to_field(), secret.low, secret.high]); // compute nullifier with this secret key so others can't descrypt it context.push_new_nullifier(nullifier, 0); // push nullifier - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("add_to_tally_public(Field)"), - [candidate] - ); + EasyPrivateVoting::at(context.this_address()).add_to_tally_public(candidate).enqueue(&mut context); } // docs:end:cast_vote diff --git a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr index e0cd1cdaf907..30fb2737fc89 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_account_contract/src/main.nr @@ -39,13 +39,6 @@ contract EcdsaAccount { actions.entrypoint(app_payload, fee_payload); } - #[aztec(private)] - #[aztec(noinitcheck)] - fn pay_init_fee(fee_payload: pub FeePayload) { - let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl); - actions.pay_init_fee(fee_payload); - } - #[aztec(private)] #[aztec(noinitcheck)] fn spend_private_authwit(inner_hash: Field) -> Field { diff --git a/noir-projects/noir-contracts/contracts/escrow_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/escrow_contract/Nargo.toml index 9982ff8b67fc..a0c107d21a4f 100644 --- a/noir-projects/noir-contracts/contracts/escrow_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/escrow_contract/Nargo.toml @@ -7,3 +7,4 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } address_note = { path = "../../../aztec-nr/address-note" } +token = { path = "../token_contract" } \ No newline at end of file diff --git a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr index 709c65b3ec58..c1ec425486b4 100644 --- a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr @@ -6,6 +6,8 @@ contract Escrow { use dep::address_note::address_note::AddressNote; + use dep::token::Token; + #[aztec(storage)] struct Storage { owner: PrivateImmutable, @@ -28,11 +30,6 @@ contract Escrow { let note = storage.owner.get_note(); assert(note.address == sender); - let selector = FunctionSelector::from_signature("transfer((Field),(Field),Field,Field)"); - let _callStackItem = context.call_private_function( - token, - selector, - [this.to_field(), recipient.to_field(), amount, 0] - ); + Token::at(token).transfer(this, recipient, amount, 0).call(&mut context); } } diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/fpc_contract/Nargo.toml index 887ffaf17d06..96bd8bacba7e 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/fpc_contract/Nargo.toml @@ -7,3 +7,5 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } authwit = { path = "../../../aztec-nr/authwit" } +token = { path = "../token_contract" } +gas_token = { path = "../gas_token_contract" } diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/fee.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/fee.nr index 84f6bdcee048..17a4ae012e7c 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/fee.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/fee.nr @@ -1,5 +1,5 @@ -use dep::aztec::context::PublicContext; +use dep::aztec::context::interface::PublicContextInterface; -pub fn calculate_fee(_context: PublicContext) -> U128 { +pub fn calculate_fee(_context: TPublicContext) -> U128 where TPublicContext: PublicContextInterface { U128::from_integer(1) } diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/interfaces.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/interfaces.nr deleted file mode 100644 index f2f94f9884a5..000000000000 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/interfaces.nr +++ /dev/null @@ -1,60 +0,0 @@ -use dep::aztec::prelude::{AztecAddress, EthAddress, FunctionSelector, PrivateContext, Deserialize}; -use dep::aztec::context::{PublicContext, gas::GasOpts}; - -struct Token { - address: AztecAddress, -} - -impl Token { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - pub fn transfer_public( - self: Self, - context: &mut PublicContext, - from: AztecAddress, - to: AztecAddress, - amount: Field, - nonce: Field - ) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("transfer_public((Field),(Field),Field,Field)"), - [from.to_field(), to.to_field(), amount, nonce], - GasOpts::default() - ).assert_empty(); - } - - pub fn shield( - self: Self, - context: &mut PublicContext, - from: AztecAddress, - amount: Field, - secret_hash: Field, - nonce: Field - ) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("shield((Field),Field,Field,Field)"), - [from.to_field(), amount, secret_hash, nonce], - GasOpts::default() - ).assert_empty(); - } - - // Private - pub fn unshield( - self: Self, - context: &mut PrivateContext, - from: AztecAddress, - to: AztecAddress, - amount: Field, - nonce: Field - ) { - context.call_private_function( - self.address, - FunctionSelector::from_signature("unshield((Field),(Field),Field,Field)"), - [from.to_field(), to.to_field(), amount, nonce] - ); - } -} diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr index 118fcd71c072..f7636711d0e3 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr @@ -1,11 +1,9 @@ -mod interfaces; - contract FPC { use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress, traits::is_empty}; use dep::aztec::state_vars::SharedImmutable; - use dep::aztec::prelude::Deserialize; + use dep::token::Token; + use dep::gas_token::GasToken; use dep::aztec::context::gas::GasOpts; - use crate::interfaces::Token; #[aztec(storage)] struct Storage { @@ -23,67 +21,34 @@ contract FPC { #[aztec(private)] fn fee_entrypoint_private(amount: Field, asset: AztecAddress, secret_hash: Field, nonce: Field) { assert(asset == storage.other_asset.read_private()); - - let _res = Token::at(asset).unshield( - &mut context, - context.msg_sender(), - context.this_address(), - amount, - nonce - ); - - let _void = context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("pay_fee_with_shielded_rebate(Field,(Field),Field)"), - [amount, asset.to_field(), secret_hash] - ); + Token::at(asset).unshield(context.msg_sender(), context.this_address(), amount, nonce).call(&mut context); + FPC::at(context.this_address()).pay_fee_with_shielded_rebate(amount, asset, secret_hash).enqueue(&mut context); } #[aztec(private)] fn fee_entrypoint_public(amount: Field, asset: AztecAddress, nonce: Field) { - let _void = context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("prepare_fee((Field),Field,(Field),Field)"), - [context.msg_sender().to_field(), amount, asset.to_field(), nonce] - ); - - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("pay_fee((Field),Field,(Field))"), - [context.msg_sender().to_field(), amount, asset.to_field()] - ); + FPC::at(context.this_address()).prepare_fee(context.msg_sender(), amount, asset, nonce).enqueue(&mut context); + FPC::at(context.this_address()).pay_fee(context.msg_sender(), amount, asset).enqueue(&mut context); } #[aztec(public)] #[aztec(internal)] fn prepare_fee(from: AztecAddress, amount: Field, asset: AztecAddress, nonce: Field) { - let _res = Token::at(asset).transfer_public(&mut context, from, context.this_address(), amount, nonce); + Token::at(asset).transfer_public(from, context.this_address(), amount, nonce).call(&mut context); } #[aztec(public)] #[aztec(internal)] fn pay_fee(refund_address: AztecAddress, amount: Field, asset: AztecAddress) { - let refund: Field = context.call_public_function( - storage.gas_token_address.read_public(), - FunctionSelector::from_signature("pay_fee(Field)"), - [amount], - GasOpts::default() - ).deserialize_into(); - + let refund = GasToken::at(storage.gas_token_address.read_public()).pay_fee(amount).call(&mut context); // Just do public refunds for the present - Token::at(asset).transfer_public(&mut context, context.this_address(), refund_address, refund, 0) + Token::at(asset).transfer_public(context.this_address(), refund_address, refund, 0).call(&mut context); } #[aztec(public)] #[aztec(internal)] fn pay_fee_with_shielded_rebate(amount: Field, asset: AztecAddress, secret_hash: Field) { - let refund: Field = context.call_public_function( - storage.gas_token_address.read_public(), - FunctionSelector::from_signature("pay_fee(Field)"), - [amount], - GasOpts::default() - ).deserialize_into(); - - Token::at(asset).shield(&mut context, context.this_address(), refund, secret_hash, 0); + let refund = GasToken::at(storage.gas_token_address.read_public()).pay_fee(amount).call(&mut context); + Token::at(asset).shield(context.this_address(), refund, secret_hash, 0).call(&mut context); } } diff --git a/noir-projects/noir-contracts/contracts/gas_token_contract/src/lib.nr b/noir-projects/noir-contracts/contracts/gas_token_contract/src/lib.nr index 9e9786bd2ed3..9e1afebac298 100644 --- a/noir-projects/noir-contracts/contracts/gas_token_contract/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/gas_token_contract/src/lib.nr @@ -1,8 +1,8 @@ use dep::aztec::prelude::{AztecAddress, EthAddress}; -use dep::aztec::context::PublicContext; +use dep::aztec::context::interface::PublicContextInterface; use dep::aztec::protocol_types::hash::sha256_to_field; -pub fn calculate_fee(_context: PublicContext) -> U128 { +pub fn calculate_fee(_context: TPublicContext) -> U128 where TPublicContext: PublicContextInterface { U128::from_integer(1) } diff --git a/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr index ba8ecf6c608d..ec1adf321160 100644 --- a/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/gas_token_contract/src/main.nr @@ -12,11 +12,11 @@ contract GasToken { } #[aztec(public)] - fn claim_public(to: AztecAddress, amount: Field, secret: Field) { + fn claim_public(to: AztecAddress, amount: Field, secret: Field, leaf_index: Field) { let content_hash = get_bridge_gas_msg_hash(to, amount); // Consume message and emit nullifier - context.consume_l1_to_l2_message(content_hash, secret, context.this_portal_address()); + context.consume_l1_to_l2_message(content_hash, secret, context.this_portal_address(), leaf_index); let new_balance = storage.balances.at(to).read() + U128::from_integer(amount); storage.balances.at(to).write(new_balance); diff --git a/noir-projects/noir-contracts/contracts/import_test_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/import_test_contract/Nargo.toml index f4ec2663e2b1..fe205fd0f171 100644 --- a/noir-projects/noir-contracts/contracts/import_test_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/import_test_contract/Nargo.toml @@ -6,3 +6,4 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } +test = { path = "../test_contract"} diff --git a/noir-projects/noir-contracts/contracts/import_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/import_test_contract/src/main.nr index 0168119b8222..9224c0c2a3e0 100644 --- a/noir-projects/noir-contracts/contracts/import_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/import_test_contract/src/main.nr @@ -1,54 +1,44 @@ -mod test_contract_interface; - // Contract that uses the autogenerated interface of the Test contract for calling its functions. // Used for testing calling into other contracts via autogenerated interfaces. contract ImportTest { - use dep::aztec::prelude::{AztecAddress, Deserialize}; + use dep::aztec::prelude::AztecAddress; + + use dep::test::{Test, Test::DeepStruct, Test::DummyNote}; - use crate::test_contract_interface::{ - TestPrivateContextInterface, TestPublicContextInterface, AStructTestCodeGenStruct, - ADeepStructTestCodeGenStruct, ANoteADeepStructTestCodeGenStruct, - ManyNotesADeepStructTestCodeGenStruct - }; + use dep::test::Test::FieldNote; + use dep::test::Test::ValueNote; // Calls the test_code_gen on the Test contract at the target address // Used for testing calling a function with arguments of multiple types // See yarn-project/simulator/src/client/private_execution.ts // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[aztec(private)] - fn main(target: AztecAddress) -> Field { - let test_contract_instance = TestPrivateContextInterface::at(target); - let returned_field: Field = test_contract_instance.test_code_gen( - &mut context, + fn main_contract(target: AztecAddress) -> Field { + Test::at(target).test_code_gen( 1, true, 1 as u32, [1, 2], - AStructTestCodeGenStruct { amount: 1, secret_hash: 2 }, - ADeepStructTestCodeGenStruct { + DummyNote { amount: 1, secret_hash: 2 }, + DeepStruct { a_field: 1, a_bool: true, - a_note: ANoteADeepStructTestCodeGenStruct { amount: 1, secret_hash: 2 }, + a_note: DummyNote { amount: 1, secret_hash: 2 }, many_notes: [ - ManyNotesADeepStructTestCodeGenStruct { amount: 1, secret_hash: 2 }, - ManyNotesADeepStructTestCodeGenStruct { amount: 1, secret_hash: 2 }, - ManyNotesADeepStructTestCodeGenStruct { amount: 1, secret_hash: 2 } + DummyNote { amount: 1, secret_hash: 2 }, + DummyNote { amount: 1, secret_hash: 2 }, + DummyNote { amount: 1, secret_hash: 2 } ] } - ).unpack_into(); - - returned_field + ).call(&mut context) } // Calls the get_this_address on the Test contract at the target address // Used for testing calling a function with no arguments // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[aztec(private)] - fn call_no_args(target: AztecAddress) -> Field { - let test_contract_instance = TestPrivateContextInterface::at(target); - let returned_field: Field = test_contract_instance.get_this_address(&mut context).unpack_into(); - - returned_field + fn call_no_args(target: AztecAddress) -> AztecAddress { + Test::at(target).get_this_address().call(&mut context) } // Calls the create_nullifier_public on the Test contract at the target address @@ -56,8 +46,7 @@ contract ImportTest { // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[aztec(private)] fn call_open_fn(target: AztecAddress) { - let test_contract_instance = TestPrivateContextInterface::at(target); - test_contract_instance.create_nullifier_public(&mut context, 1, 2); + Test::at(target).create_nullifier_public(1, 2).enqueue(&mut context); } // Calls the create_nullifier_public on the Test contract at the target address @@ -65,8 +54,7 @@ contract ImportTest { // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[aztec(public)] fn pub_call_open_fn(target: AztecAddress) { - let test_contract_instance = TestPublicContextInterface::at(target); - test_contract_instance.create_nullifier_public(&mut context, 1, 2).assert_empty(); + Test::at(target).create_nullifier_public(1, 2).call(&mut context); } } diff --git a/noir-projects/noir-contracts/contracts/import_test_contract/src/test_contract_interface.nr b/noir-projects/noir-contracts/contracts/import_test_contract/src/test_contract_interface.nr deleted file mode 120000 index 1113fbe816e4..000000000000 --- a/noir-projects/noir-contracts/contracts/import_test_contract/src/test_contract_interface.nr +++ /dev/null @@ -1 +0,0 @@ -../../test_contract/src/interface.nr \ No newline at end of file diff --git a/noir-projects/noir-contracts/contracts/key_registry_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/key_registry_contract/Nargo.toml new file mode 100644 index 000000000000..cae3a7ead7ee --- /dev/null +++ b/noir-projects/noir-contracts/contracts/key_registry_contract/Nargo.toml @@ -0,0 +1,9 @@ +[package] +name = "key_registry_contract" +authors = [""] +compiler_version = ">=0.25.0" +type = "contract" + +[dependencies] +aztec = { path = "../../../aztec-nr/aztec" } +authwit = { path = "../../../aztec-nr/authwit" } diff --git a/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr b/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr new file mode 100644 index 000000000000..8f2810f3dbf6 --- /dev/null +++ b/noir-projects/noir-contracts/contracts/key_registry_contract/src/main.nr @@ -0,0 +1,118 @@ +contract KeyRegistry { + use dep::std::hash::poseidon2::Poseidon2::hash as poseidon2_hash; + use dep::authwit::auth::assert_current_call_valid_authwit_public; + + use dep::aztec::{ + context::gas::GasOpts, + state_vars::{ + SharedMutable, + Map + }, + protocol_types::{ + abis::function_selector::FunctionSelector, + contract_class_id::ContractClassId, + address::{ + AztecAddress, + EthAddress, + PublicKeysHash, + PartialAddress, + }, + constants::{ + GENERATOR_INDEX__CONTRACT_ADDRESS_V1, + GENERATOR_INDEX__PUBLIC_KEYS_HASH + }, + traits::{ + Serialize, + Deserialize, + } + }, + }; + + global KEY_ROTATION_DELAY = 5; + + #[aztec(storage)] + struct Storage { + // We are not supporting rotating / changing keys other than the nullifier public in the registry at the moment, but will in the future. + // Uncomment lines below to enable that functionality + nullifier_public_key_registry: Map>, + // incoming_public_key_registry: Map>, + // outgoing_public_key_registry: Map>, + // tagging_public_key_registry: Map>, + } + + #[aztec(public)] + fn rotate_nullifier_public_key( + address: AztecAddress, + new_nullifier_public_key: Field, + ) { + assert( + new_nullifier_public_key != 0, + "New nullifier public key must be non-zero" + ); + + if (!address.eq(context.msg_sender())) { + assert_current_call_valid_authwit_public(&mut context, address); + } + + let nullifier_key_registry = storage.nullifier_public_key_registry.at(address); + + nullifier_key_registry.schedule_value_change(new_nullifier_public_key); + } + + #[aztec(public)] + fn register( + address: AztecAddress, + partial_address: PartialAddress, + nullifier_public_key: Field, + incoming_public_key: Field, + outgoing_public_key: Field, + tagging_public_key: Field, + ) { + assert( + (nullifier_public_key != 0) & + (incoming_public_key != 0) & + (outgoing_public_key != 0) & + (tagging_public_key != 0), + "All public keys must be non-zero" + ); + + // TODO (ek): Do it below after refactoring all public_keys_hash_elemtns + // let public_keys_hash = PublicKeysHash::compute(nullifier_public_key, tagging_public_key, incoming_public_key, outgoing_public_key); + // let address = AztecAddress::compute(public_keys_hash, partial_address); + // We could also pass in original_public_keys_hash instead of computing it here, if all we need the original one is for being able to prove ownership of address + let public_keys_hash = poseidon2_hash([ + nullifier_public_key, + incoming_public_key, + outgoing_public_key, + tagging_public_key, + GENERATOR_INDEX__PUBLIC_KEYS_HASH, + ], + 5 + ); + + let computed_address = AztecAddress::from_field( + poseidon2_hash([ + partial_address.to_field(), + public_keys_hash.to_field(), + GENERATOR_INDEX__CONTRACT_ADDRESS_V1 as Field, + ], + 3 + ) + ); + + assert(computed_address.eq(address), "Computed address does not match supplied address"); + + let nullifier_key_registry = storage.nullifier_public_key_registry.at(address); + // We are not supporting rotating / changing keys other than the nullifier public in the registry at the moment, but will in the future. + // Uncomment lines below to enable that functionality + // let incoming_key_registry = storage.incoming_public_key_registry.at(address); + // let outgoing_key_registry = storage.outgoing_public_key_registry.at(address); + // let tagging_key_registry = storage.taggin_public_key_registry.at(address); + + nullifier_key_registry.schedule_value_change(nullifier_public_key); + // We are not supporting rotating / changing keys other than the nullifier public in the registry at the moment, but will in the future. + // Uncomment lines below to enable that functionality // incoming_key_registry.schedule_value_change(new_incoming_public_key); + // outgoing_key_registry.schedule_value_change(new_outgoing_public_key); + // tagging_key_registry.schedule_value_change(new_tagging_public_key); + } +} diff --git a/noir-projects/noir-contracts/contracts/lending_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/lending_contract/Nargo.toml index e6a337360bc4..f1e58a4ef1f1 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/lending_contract/Nargo.toml @@ -6,3 +6,5 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } +token = { path = "../token_contract" } +price_feed = { path = "../price_feed_contract" } diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr index 5dc8cb7f3006..7415ec54d92c 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr +++ b/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr @@ -1,7 +1,7 @@ use dep::aztec::prelude::AztecAddress; use dep::aztec::protocol_types::traits::{Deserialize, Serialize}; -// Struct to be used to represent "totals". Generally, there should be one per asset. +// Struct to be used to represent "totals". Generally, there should be one per Asset. // It stores the global values that are shared among all users, such as an accumulator // and last time it was updated. // In practice, it should also point to an oracle and have more fields related to @@ -13,23 +13,23 @@ struct Asset { oracle: AztecAddress, } -global ASSET_SERIALIZED_LEN: Field = 4; +global SERIALIZED_LEN: Field = 4; -impl Serialize for Asset { - fn serialize(asset: Asset) -> [Field; ASSET_SERIALIZED_LEN] { +impl Serialize for Asset { + fn serialize(Asset: Asset) -> [Field; SERIALIZED_LEN] { [ - asset.interest_accumulator.to_integer(), - asset.last_updated_ts as Field, - asset.loan_to_value.to_integer(), - asset.oracle.to_field() + Asset.interest_accumulator.to_integer(), + Asset.last_updated_ts as Field, + Asset.loan_to_value.to_integer(), + Asset.oracle.to_field() ] } } -impl Deserialize for Asset { +impl Deserialize for Asset { // Right now we are wasting so many writes. If changing last_updated_ts // we will end up rewriting all of them, wasting writes. - fn deserialize(fields: [Field; ASSET_SERIALIZED_LEN]) -> Asset { + fn deserialize(fields: [Field; SERIALIZED_LEN]) -> Asset { let interest_accumulator = U128::from_integer(fields[0]); let last_updated_ts = fields[1] as u64; let loan_to_value = U128::from_integer(fields[2]); diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/interfaces.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/interfaces.nr deleted file mode 100644 index 5a2e31ec79f7..000000000000 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/interfaces.nr +++ /dev/null @@ -1,117 +0,0 @@ -use dep::aztec::prelude::{FunctionSelector, AztecAddress, PrivateContext, Deserialize}; - -use dep::aztec::context::{PublicContext, gas::GasOpts}; - -use crate::asset::Asset; - -struct PriceFeed { - address: AztecAddress, -} - -impl PriceFeed { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - pub fn get_price(self: Self, context: &mut PublicContext) -> U128 { - let price_field: Field = context.call_public_function( - self.address, - FunctionSelector::from_signature("get_price(Field)"), - [0], - GasOpts::default() - ).deserialize_into(); - - U128::from_integer(price_field) - } -} - -struct Token { - address: AztecAddress, -} - -impl Token { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - pub fn transfer_public( - self: Self, - context: &mut PublicContext, - from: AztecAddress, - to: AztecAddress, - amount: Field, - nonce: Field - ) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("transfer_public((Field),(Field),Field,Field)"), - [from.to_field(), to.to_field(), amount, nonce], - GasOpts::default() - ).assert_empty(); - } - - pub fn mint_public(self: Self, context: &mut PublicContext, to: AztecAddress, amount: Field) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("mint_public((Field),Field)"), - [to.to_field(), amount], - GasOpts::default() - ).assert_empty(); - } - - pub fn burn_public( - self: Self, - context: &mut PublicContext, - from: AztecAddress, - amount: Field, - nonce: Field - ) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("burn_public((Field),Field,Field)"), - [from.to_field(), amount, nonce], - GasOpts::default() - ).assert_empty(); - } - - // Private - pub fn unshield( - self: Self, - context: &mut PrivateContext, - from: AztecAddress, - to: AztecAddress, - amount: Field, - nonce: Field - ) { - context.call_private_function( - self.address, - FunctionSelector::from_signature("unshield((Field),(Field),Field,Field)"), - [from.to_field(), to.to_field(), amount, nonce] - ); - } - - pub fn burn(self: Self, context: &mut PrivateContext, from: AztecAddress, amount: Field, nonce: Field) { - context.call_private_function( - self.address, - FunctionSelector::from_signature("burn((Field),Field,Field)"), - [from.to_field(), amount, nonce] - ); - } -} - -struct Lending { - address: AztecAddress, -} - -impl Lending { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - pub fn update_accumulator(self: Self, context: &mut PublicContext) -> Asset { - context.call_public_function_no_args( - self.address, - FunctionSelector::from_signature("update_accumulator()") - ).deserialize_into() - } -} diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr index 37727015e257..c2c05f58a093 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr @@ -1,7 +1,6 @@ mod asset; mod interest_math; mod helpers; -mod interfaces; // Single asset CDP contract. // Shoving re-entries up the ass. @@ -17,7 +16,8 @@ contract Lending { use crate::asset::Asset; use crate::interest_math::compute_multiplier; use crate::helpers::{covered_by_collateral, DebtReturn, debt_updates, debt_value, compute_identifier}; - use crate::interfaces::{Token, Lending, PriceFeed}; + use dep::token::Token; + use dep::price_feed::PriceFeed; // Storage structure, containing all storage, and specifying what slots they use. #[aztec(storage)] @@ -49,7 +49,7 @@ contract Lending { stable_coin: AztecAddress ) { let asset_loc = storage.assets.at(0); - let asset = asset_loc.read(); + let asset: Asset = asset_loc.read(); let loan_to_value = U128::from_integer(loan_to_value); @@ -71,7 +71,7 @@ contract Lending { #[aztec(public)] fn update_accumulator() -> Asset { let asset_loc = storage.assets.at(0); - let mut asset = asset_loc.read(); + let mut asset: Asset = asset_loc.read(); let timestamp = context.timestamp(); let dt = timestamp - asset.last_updated_ts; @@ -103,38 +103,28 @@ contract Lending { collateral_asset: AztecAddress ) { let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender().to_field()); - let _res = Token::at(collateral_asset).unshield(&mut context, from, context.this_address(), amount, nonce); - // _deposit(on_behalf_of, amount, collateral_asset) - let selector = FunctionSelector::from_signature("_deposit((Field),Field,(Field))"); - context.call_public_function( - context.this_address(), - selector, - [on_behalf_of, amount, collateral_asset.to_field()] - ); + let _res = Token::at(collateral_asset).unshield(from, context.this_address(), amount, nonce).call(&mut context); + Lending::at(context.this_address())._deposit( + AztecAddress::from_field(on_behalf_of), + amount, + collateral_asset + ).enqueue(&mut context); } #[aztec(public)] fn deposit_public(amount: Field, nonce: Field, on_behalf_of: Field, collateral_asset: AztecAddress) { - Token::at(collateral_asset).transfer_public( - &mut context, - context.msg_sender(), - context.this_address(), + let _ = Token::at(collateral_asset).transfer_public(context.msg_sender(), context.this_address(), amount, nonce).call(&mut context); + let _ = Lending::at(context.this_address())._deposit( + AztecAddress::from_field(on_behalf_of), amount, - nonce - ); - let selector = FunctionSelector::from_signature("_deposit((Field),Field,(Field))"); - context.call_public_function( - context.this_address(), - selector, - [on_behalf_of, amount, collateral_asset.to_field()], - GasOpts::default() - ).assert_empty(); + collateral_asset + ).call(&mut context); } #[aztec(public)] #[aztec(internal)] fn _deposit(owner: AztecAddress, amount: Field, collateral_asset: AztecAddress) { - let _asset = Lending::at(context.this_address()).update_accumulator(&mut context); + let _asset = Lending::at(context.this_address()).update_accumulator().call(&mut context); let coll_asset = storage.collateral_asset.read(); assert(coll_asset.eq(collateral_asset)); @@ -147,30 +137,19 @@ contract Lending { #[aztec(private)] fn withdraw_private(secret: Field, to: AztecAddress, amount: Field) { let on_behalf_of = compute_identifier(secret, 0, context.msg_sender().to_field()); - let selector = FunctionSelector::from_signature("_withdraw((Field),(Field),Field)"); - context.call_public_function( - context.this_address(), - selector, - [on_behalf_of, to.to_field(), amount] - ); + Lending::at(context.this_address())._withdraw(AztecAddress::from_field(on_behalf_of), to, amount).enqueue(&mut context); } #[aztec(public)] fn withdraw_public(to: AztecAddress, amount: Field) { - let selector = FunctionSelector::from_signature("_withdraw((Field),(Field),Field)"); - context.call_public_function( - context.this_address(), - selector, - [context.msg_sender().to_field(), to.to_field(), amount], - GasOpts::default() - ).assert_empty(); + let _ = Lending::at(context.this_address())._withdraw(context.msg_sender(), to, amount).call(&mut context); } #[aztec(public)] #[aztec(internal)] fn _withdraw(owner: AztecAddress, recipient: AztecAddress, amount: Field) { - let asset = Lending::at(context.this_address()).update_accumulator(&mut context); - let price = PriceFeed::at(asset.oracle).get_price(&mut context); + let asset = Lending::at(context.this_address()).update_accumulator().call(&mut context); + let price = PriceFeed::at(asset.oracle).get_price(0).call(&mut context).price; let coll_loc = storage.collateral.at(owner); let collateral: Field = coll_loc.read(); @@ -200,36 +179,25 @@ contract Lending { // @todo @LHerskind Support both shielding and transfers (for now just transfer) let collateral_asset = storage.collateral_asset.read(); - Token::at(collateral_asset).transfer_public(&mut context, context.this_address(), recipient, amount, 0); + let _ = Token::at(collateral_asset).transfer_public(context.this_address(), recipient, amount, 0).call(&mut context); } #[aztec(private)] fn borrow_private(secret: Field, to: AztecAddress, amount: Field) { let on_behalf_of = compute_identifier(secret, 0, context.msg_sender().to_field()); - let selector = FunctionSelector::from_signature("_borrow((Field),(Field),Field)"); - context.call_public_function( - context.this_address(), - selector, - [on_behalf_of, to.to_field(), amount] - ); + let _ = Lending::at(context.this_address())._borrow(AztecAddress::from_field(on_behalf_of), to, amount).enqueue(&mut context); } #[aztec(public)] fn borrow_public(to: AztecAddress, amount: Field) { - let selector = FunctionSelector::from_signature("_borrow((Field),(Field),Field)"); - context.call_public_function( - context.this_address(), - selector, - [context.msg_sender().to_field(), to.to_field(), amount], - GasOpts::default() - ).assert_empty(); + let _ = Lending::at(context.this_address())._borrow(context.msg_sender(), to, amount).call(&mut context); } #[aztec(public)] #[aztec(internal)] fn _borrow(owner: AztecAddress, to: AztecAddress, amount: Field) { - let asset = Lending::at(context.this_address()).update_accumulator(&mut context); - let price = PriceFeed::at(asset.oracle).get_price(&mut context); + let asset = Lending::at(context.this_address()).update_accumulator().call(&mut context); + let price = PriceFeed::at(asset.oracle).get_price(0).call(&mut context).price; // Fetch collateral and static_debt, compute health of current position let collateral = U128::from_integer(storage.collateral.at(owner).read()); @@ -255,7 +223,7 @@ contract Lending { // @todo @LHerskind Need to support both private and public minting. let stable_coin = storage.stable_coin.read(); - Token::at(stable_coin).mint_public(&mut context, to, amount); + let _ = Token::at(stable_coin).mint_public(to, amount).call(&mut context); } #[aztec(private)] @@ -268,31 +236,20 @@ contract Lending { stable_coin: AztecAddress ) { let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender().to_field()); - let _res = Token::at(stable_coin).burn(&mut context, from, amount, nonce); - let selector = FunctionSelector::from_signature("_repay((Field),Field,(Field))"); - context.call_public_function( - context.this_address(), - selector, - [on_behalf_of, amount, stable_coin.to_field()] - ); + let _ = Token::at(stable_coin).burn(from, amount, nonce).call(&mut context); + let _ = Lending::at(context.this_address())._repay(AztecAddress::from_field(on_behalf_of), amount, stable_coin).enqueue(&mut context); } #[aztec(public)] fn repay_public(amount: Field, nonce: Field, owner: AztecAddress, stable_coin: AztecAddress) { - Token::at(stable_coin).burn_public(&mut context, context.msg_sender(), amount, nonce); - let selector = FunctionSelector::from_signature("_repay((Field),Field,(Field))"); - context.call_public_function( - context.this_address(), - selector, - [owner.to_field(), amount, stable_coin.to_field()], - GasOpts::default() - ).assert_empty(); + let _ = Token::at(stable_coin).burn_public(context.msg_sender(), amount, nonce).call(&mut context); + let _ = Lending::at(context.this_address())._repay(owner, amount, stable_coin).call(&mut context); } #[aztec(public)] #[aztec(internal)] fn _repay(owner: AztecAddress, amount: Field, stable_coin: AztecAddress) { - let asset = Lending::at(context.this_address()).update_accumulator(&mut context); + let asset = Lending::at(context.this_address()).update_accumulator().call(&mut context); // To ensure that private is using the correct token. assert(stable_coin.eq(storage.stable_coin.read())); @@ -315,7 +272,7 @@ contract Lending { unconstrained fn get_position(owner: AztecAddress) -> pub Position { let collateral = storage.collateral.at(owner).read(); let static_debt = storage.static_debt.at(owner).read(); - let asset = storage.assets.at(0).read(); + let asset: Asset = storage.assets.at(0).read(); let debt = debt_value( U128::from_integer(static_debt), U128::from_integer(asset.interest_accumulator) diff --git a/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr b/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr index 5dffc5e64937..fb066de5ad6d 100644 --- a/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr @@ -1,8 +1,8 @@ + // A contract used along with `Child` contract to test nested calls. contract Parent { use dep::aztec::prelude::{AztecAddress, FunctionSelector, Deserialize}; use dep::aztec::context::gas::GasOpts; - // Private function to call another private function in the target_contract using the provided selector #[aztec(private)] fn entry_point(target_contract: AztecAddress, target_selector: FunctionSelector) -> Field { @@ -20,7 +20,7 @@ contract Parent { context.call_public_function( target_contract, target_selector, - [init_value], + [init_value].as_slice(), GasOpts::default() ).deserialize_into() } @@ -35,13 +35,13 @@ contract Parent { let return_value: Field = context.call_public_function( target_contract, target_selector, - [init_value], + [init_value].as_slice(), GasOpts::default() ).deserialize_into(); context.call_public_function( target_contract, target_selector, - [return_value], + [return_value].as_slice(), GasOpts::default() ).deserialize_into() } @@ -189,7 +189,12 @@ contract Parent { target_selector: FunctionSelector, args: [Field; 1] ) -> Field { - context.static_call_public_function(target_contract, target_selector, args, GasOpts::default()).deserialize_into() + context.static_call_public_function( + target_contract, + target_selector, + args.as_slice(), + GasOpts::default() + ).deserialize_into() } // Public function to set a static context and verify correct propagation for nested public calls @@ -205,7 +210,7 @@ contract Parent { context.static_call_public_function( this_address, pub_entry_point_selector, - [target_contract.to_field(), target_selector.to_field(), args[0]], + [target_contract.to_field(), target_selector.to_field(), args[0]].as_slice(), GasOpts::default() ).deserialize_into() } diff --git a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr index f0b3f2c8ddd1..1ec2152e7c3f 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -48,17 +48,6 @@ contract SchnorrAccount { actions.entrypoint(app_payload, fee_payload); } - #[aztec(private)] - #[aztec(noinitcheck)] - fn pay_init_fee(fee_payload: pub FeePayload) { - let actions = AccountActions::private( - &mut context, - storage.approved_actions.storage_slot, - is_valid_impl - ); - actions.pay_init_fee(fee_payload); - } - #[aztec(private)] #[aztec(noinitcheck)] fn spend_private_authwit(inner_hash: Field) -> Field { diff --git a/noir-projects/noir-contracts/contracts/schnorr_hardcoded_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_hardcoded_account_contract/src/main.nr index 134a820b058f..a660670a2a5c 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_hardcoded_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_hardcoded_account_contract/src/main.nr @@ -21,12 +21,6 @@ contract SchnorrHardcodedAccount { actions.entrypoint(app_payload, fee_payload); } - #[aztec(private)] - fn pay_init_fee(fee_payload: pub FeePayload) { - let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl); - actions.pay_init_fee(fee_payload); - } - #[aztec(private)] fn spend_private_authwit(inner_hash: Field) -> Field { let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl); diff --git a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr index 2a8678ce778f..9803ed4f15e5 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr @@ -17,12 +17,6 @@ contract SchnorrSingleKeyAccount { actions.entrypoint(app_payload, fee_payload); } - #[aztec(private)] - fn pay_init_fee(fee_payload: pub FeePayload) { - let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl); - actions.pay_init_fee(fee_payload); - } - #[aztec(private)] fn spend_private_authwit(inner_hash: Field) -> Field { let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl); diff --git a/noir-projects/noir-contracts/contracts/slow_tree_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/slow_tree_contract/Nargo.toml index 54270ccd97e4..2edcc357b5ab 100644 --- a/noir-projects/noir-contracts/contracts/slow_tree_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/slow_tree_contract/Nargo.toml @@ -6,5 +6,4 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } -value_note = { path = "../../../aztec-nr/value-note" } slow_updates_tree = { path = "../../../aztec-nr/slow-updates-tree" } diff --git a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr index 2fa7b935a4b9..f71c2ff62c5a 100644 --- a/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/slow_tree_contract/src/main.nr @@ -12,7 +12,6 @@ contract SlowTree { Map, PublicMutable, PrivateSet }; - use dep::value_note::{balance_utils, utils::{increment, decrement}, value_note::ValueNote}; use dep::aztec::{context::{PublicContext, Context}, protocol_types::type_serialization::FIELD_SERIALIZED_LEN}; use dep::slow_updates_tree::{SlowMap, Leaf, SlowUpdateProof, compute_merkle_root, deserialize_slow_update_proof}; diff --git a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr index 3c7ac5c3af0d..db8efde4a25a 100644 --- a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr @@ -17,8 +17,7 @@ contract StatefulTest { #[aztec(private)] #[aztec(initializer)] fn constructor(owner: AztecAddress, value: Field) { - let selector = FunctionSelector::from_signature("create_note_no_init_check((Field),Field)"); - context.call_private_function(context.this_address(), selector, [owner.to_field(), value]).assert_empty(); + StatefulTest::at(context.this_address()).create_note_no_init_check(owner, value).call(&mut context); } #[aztec(private)] @@ -31,13 +30,7 @@ contract StatefulTest { #[aztec(public)] #[aztec(initializer)] fn public_constructor(owner: AztecAddress, value: Field) { - let selector = FunctionSelector::from_signature("increment_public_value_no_init_check((Field),Field)"); - context.call_public_function( - context.this_address(), - selector, - [owner.to_field(), value], - GasOpts::default() - ).assert_empty(); + StatefulTest::at(context.this_address()).increment_public_value_no_init_check(owner, value).call(&mut context); } #[aztec(private)] diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/interface.nr b/noir-projects/noir-contracts/contracts/test_contract/src/interface.nr deleted file mode 100644 index 711332369029..000000000000 --- a/noir-projects/noir-contracts/contracts/test_contract/src/interface.nr +++ /dev/null @@ -1,675 +0,0 @@ -/* Autogenerated file, do not edit! */ - -use dep::std; -use dep::aztec::context::{ PrivateContext, PublicContext, PackedReturns, FunctionReturns, gas::GasOpts }; -use dep::aztec::protocol_types::{ - address::AztecAddress, - abis::function_selector::FunctionSelector, -}; - -struct AddressGetPublicKeyStruct { - inner: Field, -} - -struct TargetDeployContractStruct { - inner: Field, -} - -struct SenderConsumeMessageFromArbitrarySenderPublicStruct { - inner: Field, -} - -struct ToConsumeMintPublicMessageStruct { - inner: Field, -} - -struct RecipientCreateL2ToL1MessageArbitraryRecipientPrivateStruct { - inner: Field, -} - -struct SenderConsumeMessageFromArbitrarySenderPrivateStruct { - inner: Field, -} - -struct CoinbaseAssertPublicGlobalVarsStruct { - inner: Field, -} - -struct FeeRecipientAssertPublicGlobalVarsStruct { - inner: Field, -} - -struct OwnerCallCreateNoteStruct { - inner: Field, -} - -struct AStructTestCodeGenStruct { - amount: Field, - secret_hash: Field, -} - -struct ADeepStructTestCodeGenStruct { - a_field: Field, - a_bool: bool, - a_note: ANoteADeepStructTestCodeGenStruct, - many_notes: [ManyNotesADeepStructTestCodeGenStruct;3], -} - -struct ANoteADeepStructTestCodeGenStruct { - amount: Field, - secret_hash: Field, -} - -struct ManyNotesADeepStructTestCodeGenStruct { - amount: Field, - secret_hash: Field, -} - -struct RecipientCreateL2ToL1MessageArbitraryRecipientPublicStruct { - inner: Field, -} - -struct AztecAddressGetPortalContractAddressStruct { - inner: Field, -} - - -// Interface for calling Test functions from a private context -struct TestPrivateContextInterface { - address: AztecAddress, -} - -impl TestPrivateContextInterface { - pub fn at(address: AztecAddress) -> Self { - Self { - address, - } - } - - pub fn get_public_key( - self, - context: &mut PrivateContext, - address: AddressGetPublicKeyStruct - ) -> PackedReturns{ - let mut serialized_args = [0; 1]; - serialized_args[0] = address.inner; - - context.call_private_function(self.address, FunctionSelector::from_field(0x501e4f48), serialized_args) - } - - - pub fn assert_header_public( - self, - context: &mut PrivateContext, - header_hash: Field - ) { - let mut serialized_args = [0; 1]; - serialized_args[0] = header_hash; - - context.call_public_function(self.address, FunctionSelector::from_field(0x86e38c61), serialized_args) - } - - - pub fn deploy_contract( - self, - context: &mut PrivateContext, - target: TargetDeployContractStruct - ) -> PackedReturns{ - let mut serialized_args = [0; 1]; - serialized_args[0] = target.inner; - - context.call_private_function(self.address, FunctionSelector::from_field(0x5acec588), serialized_args) - } - - - pub fn get_this_address( - self, - context: &mut PrivateContext - ) -> PackedReturns{ - let mut serialized_args = [0; 0]; - - context.call_private_function(self.address, FunctionSelector::from_field(0x95a7b2ae), serialized_args) - } - - - pub fn emit_msg_sender( - self, - context: &mut PrivateContext - ) -> PackedReturns{ - let mut serialized_args = [0; 0]; - - context.call_private_function(self.address, FunctionSelector::from_field(0x11fb5d45), serialized_args) - } - - - pub fn consume_message_from_arbitrary_sender_public( - self, - context: &mut PrivateContext, - content: Field, - secret: Field, - sender: SenderConsumeMessageFromArbitrarySenderPublicStruct - ) { - let mut serialized_args = [0; 3]; - serialized_args[0] = content; - serialized_args[1] = secret; - serialized_args[2] = sender.inner; - - context.call_public_function(self.address, FunctionSelector::from_field(0x42ca6d60), serialized_args) - } - - - pub fn emit_unencrypted( - self, - context: &mut PrivateContext, - value: Field - ) { - let mut serialized_args = [0; 1]; - serialized_args[0] = value; - - context.call_public_function(self.address, FunctionSelector::from_field(0x817a64cb), serialized_args) - } - - - pub fn consume_mint_public_message( - self, - context: &mut PrivateContext, - to: ToConsumeMintPublicMessageStruct, - amount: Field, - secret: Field - ) { - let mut serialized_args = [0; 3]; - serialized_args[0] = to.inner; - serialized_args[1] = amount; - serialized_args[2] = secret; - - context.call_public_function(self.address, FunctionSelector::from_field(0xa0f84219), serialized_args) - } - - - pub fn create_nullifier_public( - self, - context: &mut PrivateContext, - amount: Field, - secret_hash: Field - ) { - let mut serialized_args = [0; 2]; - serialized_args[0] = amount; - serialized_args[1] = secret_hash; - - context.call_public_function(self.address, FunctionSelector::from_field(0xdf02db8d), serialized_args) - } - - - pub fn call_get_notes_many( - self, - context: &mut PrivateContext, - storage_slot: Field, - active_or_nullified: bool - ) -> PackedReturns{ - let mut serialized_args = [0; 2]; - serialized_args[0] = storage_slot; - serialized_args[1] = active_or_nullified as Field; - - context.call_private_function(self.address, FunctionSelector::from_field(0xcfcadbce), serialized_args) - } - - - pub fn create_l2_to_l1_message_arbitrary_recipient_private( - self, - context: &mut PrivateContext, - content: Field, - recipient: RecipientCreateL2ToL1MessageArbitraryRecipientPrivateStruct - ) -> PackedReturns{ - let mut serialized_args = [0; 2]; - serialized_args[0] = content; - serialized_args[1] = recipient.inner; - - context.call_private_function(self.address, FunctionSelector::from_field(0xaccc5d5d), serialized_args) - } - - - pub fn consume_message_from_arbitrary_sender_private( - self, - context: &mut PrivateContext, - content: Field, - secret: Field, - sender: SenderConsumeMessageFromArbitrarySenderPrivateStruct - ) -> PackedReturns{ - let mut serialized_args = [0; 3]; - serialized_args[0] = content; - serialized_args[1] = secret; - serialized_args[2] = sender.inner; - - context.call_private_function(self.address, FunctionSelector::from_field(0x2847cb26), serialized_args) - } - - - pub fn create_l2_to_l1_message_public( - self, - context: &mut PrivateContext, - amount: Field, - secret_hash: Field - ) { - let mut serialized_args = [0; 2]; - serialized_args[0] = amount; - serialized_args[1] = secret_hash; - - context.call_public_function(self.address, FunctionSelector::from_field(0x9749ca06), serialized_args) - } - - - pub fn is_time_equal( - self, - context: &mut PrivateContext, - time: u64 - ) { - let mut serialized_args = [0; 1]; - serialized_args[0] = time as Field; - - context.call_public_function(self.address, FunctionSelector::from_field(0xb5bb17fa), serialized_args) - } - - - pub fn assert_private_global_vars( - self, - context: &mut PrivateContext, - chain_id: Field, - version: Field - ) -> PackedReturns{ - let mut serialized_args = [0; 2]; - serialized_args[0] = chain_id; - serialized_args[1] = version; - - context.call_private_function(self.address, FunctionSelector::from_field(0x7a8e9b66), serialized_args) - } - - - pub fn assert_public_global_vars( - self, - context: &mut PrivateContext, - chain_id: Field, - version: Field, - block_number: Field, - timestamp: u64, - coinbase: CoinbaseAssertPublicGlobalVarsStruct, - fee_recipient: FeeRecipientAssertPublicGlobalVarsStruct, - fee_per_da_gas: Field, - fee_per_l1_gas: Field, - fee_per_l2_gas: Field - ) { - let mut serialized_args = [0; 9]; - serialized_args[0] = chain_id; - serialized_args[1] = version; - serialized_args[2] = block_number; - serialized_args[3] = timestamp as Field; - serialized_args[4] = coinbase.inner; - serialized_args[5] = fee_recipient.inner; - serialized_args[6] = fee_per_da_gas; - serialized_args[7] = fee_per_l1_gas; - serialized_args[8] = fee_per_l2_gas; - - context.call_public_function(self.address, FunctionSelector::from_field(0x33b3a245), serialized_args) - } - - - pub fn consume_note_from_secret( - self, - context: &mut PrivateContext, - secret: Field - ) -> PackedReturns{ - let mut serialized_args = [0; 1]; - serialized_args[0] = secret; - - context.call_private_function(self.address, FunctionSelector::from_field(0x754932c8), serialized_args) - } - - - pub fn call_destroy_note( - self, - context: &mut PrivateContext, - storage_slot: Field - ) -> PackedReturns{ - let mut serialized_args = [0; 1]; - serialized_args[0] = storage_slot; - - context.call_private_function(self.address, FunctionSelector::from_field(0xf52a62f7), serialized_args) - } - - - pub fn call_create_note( - self, - context: &mut PrivateContext, - value: Field, - owner: OwnerCallCreateNoteStruct, - storage_slot: Field - ) -> PackedReturns{ - let mut serialized_args = [0; 3]; - serialized_args[0] = value; - serialized_args[1] = owner.inner; - serialized_args[2] = storage_slot; - - context.call_private_function(self.address, FunctionSelector::from_field(0x946991ff), serialized_args) - } - - - pub fn get_this_portal_address( - self, - context: &mut PrivateContext - ) -> PackedReturns{ - let mut serialized_args = [0; 0]; - - context.call_private_function(self.address, FunctionSelector::from_field(0xc71384f5), serialized_args) - } - - - pub fn call_get_notes( - self, - context: &mut PrivateContext, - storage_slot: Field, - active_or_nullified: bool - ) -> PackedReturns{ - let mut serialized_args = [0; 2]; - serialized_args[0] = storage_slot; - serialized_args[1] = active_or_nullified as Field; - - context.call_private_function(self.address, FunctionSelector::from_field(0x11eeb3ea), serialized_args) - } - - - pub fn test_code_gen( - self, - context: &mut PrivateContext, - a_field: Field, - a_bool: bool, - a_number: u32, - an_array: [Field;2], - a_struct: AStructTestCodeGenStruct, - a_deep_struct: ADeepStructTestCodeGenStruct - ) -> PackedReturns{ - let mut serialized_args = [0; 17]; - serialized_args[0] = a_field; - serialized_args[1] = a_bool as Field; - serialized_args[2] = a_number as Field; - serialized_args[3] = an_array[0]; - serialized_args[4] = an_array[1]; - serialized_args[5] = a_struct.amount; - serialized_args[6] = a_struct.secret_hash; - serialized_args[7] = a_deep_struct.a_field; - serialized_args[8] = a_deep_struct.a_bool as Field; - serialized_args[9] = a_deep_struct.a_note.amount; - serialized_args[10] = a_deep_struct.a_note.secret_hash; - serialized_args[11] = a_deep_struct.many_notes[0].amount; - serialized_args[12] = a_deep_struct.many_notes[0].secret_hash; - serialized_args[13] = a_deep_struct.many_notes[1].amount; - serialized_args[14] = a_deep_struct.many_notes[1].secret_hash; - serialized_args[15] = a_deep_struct.many_notes[2].amount; - serialized_args[16] = a_deep_struct.many_notes[2].secret_hash; - - context.call_private_function(self.address, FunctionSelector::from_field(0x0f054f9b), serialized_args) - } - - - pub fn set_constant( - self, - context: &mut PrivateContext, - value: Field - ) -> PackedReturns{ - let mut serialized_args = [0; 1]; - serialized_args[0] = value; - - context.call_private_function(self.address, FunctionSelector::from_field(0x1b3b9e18), serialized_args) - } - - - pub fn consume_mint_private_message( - self, - context: &mut PrivateContext, - secret_hash_for_redeeming_minted_notes: Field, - amount: Field, - secret_for_L1_to_L2_message_consumption: Field - ) -> PackedReturns{ - let mut serialized_args = [0; 3]; - serialized_args[0] = secret_hash_for_redeeming_minted_notes; - serialized_args[1] = amount; - serialized_args[2] = secret_for_L1_to_L2_message_consumption; - - context.call_private_function(self.address, FunctionSelector::from_field(0xa0fdbaa9), serialized_args) - } - - - pub fn create_l2_to_l1_message_arbitrary_recipient_public( - self, - context: &mut PrivateContext, - content: Field, - recipient: RecipientCreateL2ToL1MessageArbitraryRecipientPublicStruct - ) { - let mut serialized_args = [0; 2]; - serialized_args[0] = content; - serialized_args[1] = recipient.inner; - - context.call_public_function(self.address, FunctionSelector::from_field(0x2fb25188), serialized_args) - } - - - pub fn emit_nullifier( - self, - context: &mut PrivateContext, - nullifier: Field - ) -> PackedReturns{ - let mut serialized_args = [0; 1]; - serialized_args[0] = nullifier; - - context.call_private_function(self.address, FunctionSelector::from_field(0x82a8b183), serialized_args) - } - - - pub fn emit_array_as_unencrypted_log( - self, - context: &mut PrivateContext, - fields: [Field;5] - ) -> PackedReturns{ - let mut serialized_args = [0; 5]; - serialized_args[0] = fields[0]; - serialized_args[1] = fields[1]; - serialized_args[2] = fields[2]; - serialized_args[3] = fields[3]; - serialized_args[4] = fields[4]; - - context.call_private_function(self.address, FunctionSelector::from_field(0xe25cbdd3), serialized_args) - } - - - pub fn get_portal_contract_address( - self, - context: &mut PrivateContext, - aztec_address: AztecAddressGetPortalContractAddressStruct - ) -> PackedReturns{ - let mut serialized_args = [0; 1]; - serialized_args[0] = aztec_address.inner; - - context.call_private_function(self.address, FunctionSelector::from_field(0x30e5344b), serialized_args) - } - - - pub fn request_max_block_number( - self, - context: &mut PrivateContext, - max_block_number: u32, - enqueue_public_call: bool - ) -> PackedReturns{ - let mut serialized_args = [0; 2]; - serialized_args[0] = max_block_number as Field; - serialized_args[1] = enqueue_public_call as Field; - - context.call_private_function(self.address, FunctionSelector::from_field(0x6db24b2e), serialized_args) - } - - - pub fn assert_header_private( - self, - context: &mut PrivateContext, - header_hash: Field - ) -> PackedReturns{ - let mut serialized_args = [0; 1]; - serialized_args[0] = header_hash; - - context.call_private_function(self.address, FunctionSelector::from_field(0x4e45eb9e), serialized_args) - } - -} - - - - -// Interface for calling Test functions from a public context -struct TestPublicContextInterface { - address: AztecAddress, -} - -impl TestPublicContextInterface { - pub fn at(address: AztecAddress) -> Self { - Self { - address, - } - } - - pub fn assert_header_public( - self, - context: &mut PublicContext, - header_hash: Field - ) -> FunctionReturns { - let mut serialized_args = [0; 1]; - serialized_args[0] = header_hash; - - context.call_public_function(self.address, FunctionSelector::from_field(0x86e38c61), serialized_args, GasOpts::default()) - } - - - pub fn consume_message_from_arbitrary_sender_public( - self, - context: &mut PublicContext, - content: Field, - secret: Field, - sender: SenderConsumeMessageFromArbitrarySenderPublicStruct - ) -> FunctionReturns { - let mut serialized_args = [0; 3]; - serialized_args[0] = content; - serialized_args[1] = secret; - serialized_args[2] = sender.inner; - - context.call_public_function(self.address, FunctionSelector::from_field(0x42ca6d60), serialized_args, GasOpts::default()) - } - - - pub fn emit_unencrypted( - self, - context: &mut PublicContext, - value: Field - ) -> FunctionReturns { - let mut serialized_args = [0; 1]; - serialized_args[0] = value; - - context.call_public_function(self.address, FunctionSelector::from_field(0x817a64cb), serialized_args, GasOpts::default()) - } - - - pub fn consume_mint_public_message( - self, - context: &mut PublicContext, - to: ToConsumeMintPublicMessageStruct, - amount: Field, - secret: Field - ) -> FunctionReturns { - let mut serialized_args = [0; 3]; - serialized_args[0] = to.inner; - serialized_args[1] = amount; - serialized_args[2] = secret; - - context.call_public_function(self.address, FunctionSelector::from_field(0xa0f84219), serialized_args, GasOpts::default()) - } - - - pub fn create_nullifier_public( - self, - context: &mut PublicContext, - amount: Field, - secret_hash: Field - ) -> FunctionReturns { - let mut serialized_args = [0; 2]; - serialized_args[0] = amount; - serialized_args[1] = secret_hash; - - context.call_public_function(self.address, FunctionSelector::from_field(0xdf02db8d), serialized_args, GasOpts::default()) - } - - - pub fn create_l2_to_l1_message_public( - self, - context: &mut PublicContext, - amount: Field, - secret_hash: Field - ) -> FunctionReturns { - let mut serialized_args = [0; 2]; - serialized_args[0] = amount; - serialized_args[1] = secret_hash; - - context.call_public_function(self.address, FunctionSelector::from_field(0x9749ca06), serialized_args, GasOpts::default()) - } - - - pub fn is_time_equal( - self, - context: &mut PublicContext, - time: u64 - ) -> FunctionReturns { - let mut serialized_args = [0; 1]; - serialized_args[0] = time as Field; - - context.call_public_function(self.address, FunctionSelector::from_field(0xb5bb17fa), serialized_args, GasOpts::default()) - } - - - pub fn assert_public_global_vars( - self, - context: &mut PublicContext, - chain_id: Field, - version: Field, - block_number: Field, - timestamp: u64, - coinbase: CoinbaseAssertPublicGlobalVarsStruct, - fee_recipient: FeeRecipientAssertPublicGlobalVarsStruct, - fee_per_da_gas: Field, - fee_per_l1_gas: Field, - fee_per_l2_gas: Field - ) -> FunctionReturns { - let mut serialized_args = [0; 9]; - serialized_args[0] = chain_id; - serialized_args[1] = version; - serialized_args[2] = block_number; - serialized_args[3] = timestamp as Field; - serialized_args[4] = coinbase.inner; - serialized_args[5] = fee_recipient.inner; - serialized_args[6] = fee_per_da_gas; - serialized_args[7] = fee_per_l1_gas; - serialized_args[8] = fee_per_l2_gas; - - context.call_public_function(self.address, FunctionSelector::from_field(0x33b3a245), serialized_args, GasOpts::default()) - } - - - pub fn create_l2_to_l1_message_arbitrary_recipient_public( - self, - context: &mut PublicContext, - content: Field, - recipient: RecipientCreateL2ToL1MessageArbitraryRecipientPublicStruct - ) -> FunctionReturns { - let mut serialized_args = [0; 2]; - serialized_args[0] = content; - serialized_args[1] = recipient.inner; - - context.call_public_function(self.address, FunctionSelector::from_field(0x2fb25188), serialized_args, GasOpts::default()) - } - -} - - diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index 663cafa48601..851b8e59ee64 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -7,8 +7,13 @@ contract Test { use dep::aztec::protocol_types::{ abis::private_circuit_public_inputs::PrivateCircuitPublicInputs, - constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NOTES_PER_PAGE} + constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL}, traits::Serialize }; + + use dep::aztec::note::constants::MAX_NOTES_PER_PAGE; + + use dep::aztec::state_vars::shared_mutable::SharedMutablePrivateGetter; + // docs:start:unencrypted_import use dep::aztec::prelude::emit_unencrypted_log; // docs:end:unencrypted_import @@ -72,11 +77,7 @@ contract Test { context.set_tx_max_block_number(max_block_number); if enqueue_public_call { - let _ = context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("dummy_public_call()"), - [] - ); + Test::at(context.this_address()).dummy_public_call().enqueue(&mut context) } } @@ -179,18 +180,15 @@ contract Test { destroy_note(&mut context, note); } - // Test codegen for Aztec.nr interfaces - // See yarn-project/simulator/src/client/private_execution.test.ts 'nested calls through autogenerated interface' - // Note; this function is deliberately NOT annotated with #[aztec(private)] due to its use in tests + #[aztec(private)] fn test_code_gen( - inputs: PrivateContextInputs, a_field: Field, a_bool: bool, a_number: u32, an_array: [Field; 2], a_struct: DummyNote, a_deep_struct: DeepStruct - ) -> distinct pub PrivateCircuitPublicInputs { + ) -> Field { let mut args = ArgsHasher::new(); args.add(a_field); args.add(a_bool as Field); @@ -206,12 +204,7 @@ contract Test { args.add(note.amount); args.add(note.secret_hash); } - let args_hash = args.hash(); - let mut context = PrivateContext::new(inputs, args_hash); - let mut returns = ArgsHasher::new(); - returns.add(args_hash); - context.set_return_hash(returns); - context.finish() + args.hash() } // Purely exists for testing @@ -280,10 +273,20 @@ contract Test { } #[aztec(public)] - fn consume_mint_public_message(to: AztecAddress, amount: Field, secret: Field) { + fn consume_mint_public_message( + to: AztecAddress, + amount: Field, + secret: Field, + message_leaf_index: Field + ) { let content_hash = get_mint_public_content_hash(to, amount); // Consume message and emit nullifier - context.consume_l1_to_l2_message(content_hash, secret, context.this_portal_address()); + context.consume_l1_to_l2_message( + content_hash, + secret, + context.this_portal_address(), + message_leaf_index + ); } #[aztec(private)] @@ -305,10 +308,11 @@ contract Test { fn consume_message_from_arbitrary_sender_public( content: Field, secret: Field, - sender: EthAddress + sender: EthAddress, + message_leaf_index: Field ) { // Consume message and emit nullifier - context.consume_l1_to_l2_message(content, secret, sender); + context.consume_l1_to_l2_message(content, secret, sender, message_leaf_index); } #[aztec(private)] @@ -388,6 +392,42 @@ contract Test { constant.value } + #[aztec(private)] + fn test_shared_mutable_private_getter_for_registry_contract( + contract_address_to_read: AztecAddress, + storage_slot_of_shared_mutable: Field, + address_to_get_in_registry: AztecAddress, + ) { + // We have to derive this slot to get the location of the shared mutable inside the Map + let derived_slot = dep::aztec::hash::pedersen_hash([storage_slot_of_shared_mutable, address_to_get_in_registry.to_field()], 0); + // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly + let registry_private_getter: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(context, contract_address_to_read, derived_slot); + let nullifier_public_key = registry_private_getter.get_current_value_in_private(); + + emit_unencrypted_log_from_private(&mut context, nullifier_public_key); + } + + #[aztec(private)] + fn test_shared_mutable_private_getter( + contract_address_to_read: AztecAddress, + storage_slot_of_shared_mutable: Field, + ) { + // It's a bit wonky because we need to know the delay for get_current_value_in_private to work correctly + let test: SharedMutablePrivateGetter = SharedMutablePrivateGetter::new(context, contract_address_to_read, storage_slot_of_shared_mutable); + let authorized = test.get_current_value_in_private(); + + emit_unencrypted_log_from_private(&mut context, authorized); + } + + #[aztec(public)] + fn delay() { + // We use this as a util function to "mine a block" + dep::aztec::log::emit_unencrypted_log( + &mut context, + "dummy" + ); + } + // Purely exists for testing unconstrained fn get_random(kinda_seed: Field) -> pub Field { kinda_seed * unsafe_rand() @@ -408,10 +448,36 @@ contract Test { } } + impl Serialize<2> for DummyNote { + fn serialize(self) -> [Field; 2] { + [self.amount, self.secret_hash] + } + } + struct DeepStruct { a_field: Field, a_bool: bool, a_note: DummyNote, many_notes: [DummyNote; 3], } + + // Serializing using "canonical" form. + // 1. Everything that fits in a field, *becomes* a Field + // 2. Strings become arrays of bytes (no strings here) + // 4. Arrays become arrays of Fields following rules 2 and 3 (no arrays here) + // 5. Structs become arrays of Fields, with every item defined in the same order as they are in Noir code, following rules 2, 3, 4 and 5 (recursive) + impl Serialize<10> for DeepStruct { + fn serialize(self) -> [Field; 10] { + let mut result = [0; 10]; + result[0] = self.a_field; + result[1] = self.a_bool as Field; + result[2] = self.a_note.amount; + result[3] = self.a_note.secret_hash; + for i in 0..3 { + result[4 + i * 2] = self.many_notes[i].amount; + result[5 + i * 2] = self.many_notes[i].secret_hash; + } + result + } + } } diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/token_blacklist_contract/Nargo.toml index 493c91593321..54bc420b8043 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/Nargo.toml @@ -8,3 +8,4 @@ type = "contract" aztec = { path = "../../../aztec-nr/aztec" } field_note = { path = "../../../aztec-nr/field-note" } authwit = { path = "../../../aztec-nr/authwit" } +slow_tree = { path = "../slow_tree_contract" } \ No newline at end of file diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/interfaces.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/interfaces.nr deleted file mode 100644 index 601d9ba65f01..000000000000 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/interfaces.nr +++ /dev/null @@ -1,45 +0,0 @@ -use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}; -use dep::aztec::prelude::Deserialize; -use dep::aztec::context::{PrivateContext, PublicContext, Context, gas::GasOpts}; - -struct SlowMap { - address: AztecAddress, -} - -impl SlowMap { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - pub fn initialize(self: Self, context: &mut PublicContext) { - context.call_public_function_no_args( - self.address, - FunctionSelector::from_signature("initialize()") - ).assert_empty(); - } - - pub fn read_at_pub(self: Self, context: &mut PublicContext, index: Field) -> Field { - context.call_public_function( - self.address, - FunctionSelector::from_signature("read_at_pub(Field)"), - [index], - GasOpts::default() - ).deserialize_into() - } - - pub fn read_at(self: Self, context: &mut PrivateContext, index: Field) -> Field { - context.call_private_function( - self.address, - FunctionSelector::from_signature("read_at(Field)"), - [index] - ).unpack_into() - } - - pub fn update_at_private(self: Self, context: &mut PrivateContext, index: Field, new_value: Field) { - let _ = context.call_private_function( - self.address, - FunctionSelector::from_signature("update_at_private(Field,Field)"), - [index, new_value] - ); - } -} diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr index cfad6717cc96..ddb115c721ef 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -1,6 +1,4 @@ mod types; -mod interfaces; - // Minimal token implementation that supports `AuthWit` accounts and the slow update tree. // The auth message follows a similar pattern to the cross-chain message and includes a designated caller. // The designated caller is ALWAYS used here, and not based on a flag as cross-chain. @@ -27,7 +25,7 @@ contract TokenBlacklist { use crate::types::{transparent_note::TransparentNote, token_note::TokenNote, balances_map::BalancesMap, roles::UserFlags}; // docs:start:interface - use crate::interfaces::SlowMap; + use dep::slow_tree::SlowTree; // docs:end:interface #[aztec(storage)] @@ -51,25 +49,20 @@ contract TokenBlacklist { storage.slow_update.initialize(slow_updates_contract); // docs:end:write_slow_update_public // docs:start:slowmap_initialize - SlowMap::at(slow_updates_contract).initialize(&mut context); + SlowTree::at(slow_updates_contract).initialize().call(&mut context); // docs:end:slowmap_initialize // We cannot do the following atm // let roles = UserFlags { is_admin: true, is_minter: false, is_blacklisted: false }.get_value().to_field(); - // SlowMap::at(slow_updates_contract).update_at_private(&mut context, admin.to_field(), roles); + // SlowTree::at(slow_updates_contract).update_at_private(&mut context, admin.to_field(), roles); } #[aztec(private)] fn init_slow_tree(user: AztecAddress) { let roles = UserFlags { is_admin: true, is_minter: false, is_blacklisted: false }.get_value().to_field(); // docs:start:get_and_update_private - let slow = SlowMap::at(storage.slow_update.read_private()); - slow.update_at_private(&mut context, user.to_field(), roles); + SlowTree::at(storage.slow_update.read_private()).update_at_private(user.to_field(), roles).call(&mut context); // docs:end:get_and_update_private - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("_init_slow_tree((Field))"), - [context.msg_sender().to_field()] - ); + TokenBlacklist::at(context.this_address())._init_slow_tree(context.msg_sender()).enqueue(&mut context); } #[aztec(public)] @@ -81,25 +74,27 @@ contract TokenBlacklist { #[aztec(private)] fn update_roles(user: AztecAddress, roles: Field) { // docs:start:slowmap_at - let slow = SlowMap::at(storage.slow_update.read_private()); + let slow = SlowTree::at(storage.slow_update.read_private()); // docs:end:slowmap_at - let caller_roles = UserFlags::new(U128::from_integer(slow.read_at(&mut context, context.msg_sender().to_field()))); + let role = slow.read_at(context.msg_sender().to_field()).call(&mut context); + + let caller_roles = UserFlags::new(U128::from_integer(role)); assert(caller_roles.is_admin, "caller is not admin"); - slow.update_at_private(&mut context, user.to_field(), roles); + slow.update_at_private(user.to_field(), roles).call(&mut context); } #[aztec(public)] fn mint_public(to: AztecAddress, amount: Field) { // docs:start:get_public - let slow = SlowMap::at(storage.slow_update.read_public()); + let slow = SlowTree::at(storage.slow_update.read_public()); // docs:end:get_public // docs:start:read_at_pub - let to_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(&mut context, to.to_field()))); + let to_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(to.to_field()).call(&mut context))); // docs:end:read_at_pub assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); - let caller_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(&mut context, context.msg_sender().to_field()))); + let caller_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(context.msg_sender().to_field()).call(&mut context))); assert(caller_roles.is_minter, "caller is not minter"); let amount = U128::from_integer(amount); @@ -112,8 +107,8 @@ contract TokenBlacklist { #[aztec(public)] fn mint_private(amount: Field, secret_hash: Field) { - let slow = SlowMap::at(storage.slow_update.read_public()); - let caller_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(&mut context, context.msg_sender().to_field()))); + let slow = SlowTree::at(storage.slow_update.read_public()); + let caller_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(context.msg_sender().to_field()).call(&mut context))); assert(caller_roles.is_minter, "caller is not minter"); let pending_shields = storage.pending_shields; @@ -126,8 +121,8 @@ contract TokenBlacklist { #[aztec(public)] fn shield(from: AztecAddress, amount: Field, secret_hash: Field, nonce: Field) { - let slow = SlowMap::at(storage.slow_update.read_public()); - let from_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(&mut context, from.to_field()))); + let slow = SlowTree::at(storage.slow_update.read_public()); + let from_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(from.to_field()).call(&mut context))); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); if (!from.eq(context.msg_sender())) { @@ -149,10 +144,10 @@ contract TokenBlacklist { #[aztec(public)] fn transfer_public(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { - let slow = SlowMap::at(storage.slow_update.read_public()); - let from_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(&mut context, from.to_field()))); + let slow = SlowTree::at(storage.slow_update.read_public()); + let from_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(from.to_field()).call(&mut context))); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let to_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(&mut context, to.to_field()))); + let to_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(to.to_field()).call(&mut context))); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); if (!from.eq(context.msg_sender())) { @@ -171,8 +166,8 @@ contract TokenBlacklist { #[aztec(public)] fn burn_public(from: AztecAddress, amount: Field, nonce: Field) { - let slow = SlowMap::at(storage.slow_update.read_public()); - let from_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(&mut context, from.to_field()))); + let slow = SlowTree::at(storage.slow_update.read_public()); + let from_roles = UserFlags::new(U128::from_integer(slow.read_at_pub(from.to_field()).call(&mut context))); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); if (!from.eq(context.msg_sender())) { @@ -191,9 +186,9 @@ contract TokenBlacklist { #[aztec(private)] fn redeem_shield(to: AztecAddress, amount: Field, secret: Field) { - let slow = SlowMap::at(storage.slow_update.read_private()); + let slow = SlowTree::at(storage.slow_update.read_private()); // docs:start:slowmap_read_at - let to_roles = UserFlags::new(U128::from_integer(slow.read_at(&mut context, to.to_field()))); + let to_roles = UserFlags::new(U128::from_integer(slow.read_at(to.to_field()).call(&mut context))); // docs:end:slowmap_read_at assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); @@ -218,10 +213,10 @@ contract TokenBlacklist { #[aztec(private)] fn unshield(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { - let slow = SlowMap::at(storage.slow_update.read_private()); - let from_roles = UserFlags::new(U128::from_integer(slow.read_at(&mut context, from.to_field()))); + let slow = SlowTree::at(storage.slow_update.read_private()); + let from_roles = UserFlags::new(U128::from_integer(slow.read_at(from.to_field()).call(&mut context))); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let to_roles = UserFlags::new(U128::from_integer(slow.read_at(&mut context, to.to_field()))); + let to_roles = UserFlags::new(U128::from_integer(slow.read_at(to.to_field()).call(&mut context))); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); if (!from.eq(context.msg_sender())) { @@ -239,10 +234,10 @@ contract TokenBlacklist { // docs:start:transfer_private #[aztec(private)] fn transfer(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { - let slow = SlowMap::at(storage.slow_update.read_private()); - let from_roles = UserFlags::new(U128::from_integer(slow.read_at(&mut context, from.to_field()))); + let slow = SlowTree::at(storage.slow_update.read_private()); + let from_roles = UserFlags::new(U128::from_integer(slow.read_at(from.to_field()).call(&mut context))); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let to_roles = UserFlags::new(U128::from_integer(slow.read_at(&mut context, to.to_field()))); + let to_roles = UserFlags::new(U128::from_integer(slow.read_at(to.to_field()).call(&mut context))); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); // docs:end:transfer_private @@ -259,8 +254,8 @@ contract TokenBlacklist { #[aztec(private)] fn burn(from: AztecAddress, amount: Field, nonce: Field) { - let slow = SlowMap::at(storage.slow_update.read_private()); - let from_roles = UserFlags::new(U128::from_integer(slow.read_at(&mut context, from.to_field()))); + let slow = SlowTree::at(storage.slow_update.read_private()); + let from_roles = UserFlags::new(U128::from_integer(slow.read_at(from.to_field()).call(&mut context))); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); if (!from.eq(context.msg_sender())) { diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/token_bridge_contract/Nargo.toml index da41973739d7..75c729d9c504 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/Nargo.toml @@ -7,3 +7,4 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } token_portal_content_hash_lib = { path = "../token_portal_content_hash_lib" } +token = { path = "../token_contract" } diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index 673e4b8aa7f8..32f9653915b7 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -1,5 +1,4 @@ // docs:start:token_bridge_imports -mod token_interface; // Minimal implementation of the token bridge that can move funds between L1 <> L2. // The bridge has a corresponding Portal contract on L1 that it is attached to @@ -13,7 +12,7 @@ contract TokenBridge { use dep::token_portal_content_hash_lib::{get_mint_public_content_hash, get_mint_private_content_hash, get_withdraw_content_hash}; - use crate::token_interface::Token; + use dep::token::Token; // docs:end:token_bridge_imports // docs:start:token_bridge_storage_and_constructor @@ -35,14 +34,19 @@ contract TokenBridge { // docs:start:claim_public // Consumes a L1->L2 message and calls the token contract to mint the appropriate amount publicly #[aztec(public)] - fn claim_public(to: AztecAddress, amount: Field, secret: Field) { + fn claim_public(to: AztecAddress, amount: Field, secret: Field, message_leaf_index: Field) { let content_hash = get_mint_public_content_hash(to, amount); // Consume message and emit nullifier - context.consume_l1_to_l2_message(content_hash, secret, context.this_portal_address()); + context.consume_l1_to_l2_message( + content_hash, + secret, + context.this_portal_address(), + message_leaf_index + ); // Mint tokens - Token::at(storage.token.read()).mint_public(&mut context, to, amount); + Token::at(storage.token.read()).mint_public(to, amount).call(&mut context); } // docs:end:claim_public @@ -61,7 +65,7 @@ contract TokenBridge { context.message_portal(context.this_portal_address(), content); // Burn tokens - Token::at(storage.token.read()).burn_public(&mut context, context.msg_sender(), amount, nonce); + Token::at(storage.token.read()).burn_public(context.msg_sender(), amount, nonce).call(&mut context); } // docs:end:exit_to_l1_public // docs:start:claim_private @@ -118,7 +122,7 @@ contract TokenBridge { // docs:end:call_assert_token_is_same // Burn tokens - Token::at(token).burn(&mut context, context.msg_sender(), amount, nonce); + Token::at(token).burn(context.msg_sender(), amount, nonce).call(&mut context); } /// docs:end:exit_to_l1_private @@ -151,7 +155,7 @@ contract TokenBridge { #[aztec(public)] #[aztec(internal)] fn _call_mint_on_token(amount: Field, secret_hash: Field) { - Token::at(storage.token.read()).mint_private(&mut context, amount, secret_hash); + Token::at(storage.token.read()).mint_private(amount, secret_hash).call(&mut context); } // docs:end:call_mint_on_token diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/token_interface.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/token_interface.nr deleted file mode 100644 index 8cebb78da04c..000000000000 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/token_interface.nr +++ /dev/null @@ -1,59 +0,0 @@ -// docs:start:token_bridge_token_interface -use dep::aztec::prelude::{FunctionSelector, AztecAddress, EthAddress, PrivateContext}; -use dep::aztec::context::{PublicContext, Context, gas::GasOpts}; - -struct Token { - address: AztecAddress, -} - -impl Token { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - pub fn mint_public(self: Self, context: &mut PublicContext, to: AztecAddress, amount: Field) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("mint_public((Field),Field)"), - [to.to_field(), amount], - GasOpts::default() - ).assert_empty(); - } - - // docs:start:public_burn_interface - pub fn burn_public( - self: Self, - context: &mut PublicContext, - from: AztecAddress, - amount: Field, - nonce: Field - ) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("burn_public((Field),Field,Field)"), - [from.to_field(), amount, nonce], - GasOpts::default() - ).assert_empty(); - } - // docs:end:public_burn_interface - - pub fn mint_private(self: Self, context: &mut PublicContext, amount: Field, secret_hash: Field) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("mint_private(Field,Field)"), - [amount, secret_hash], - GasOpts::default() - ).assert_empty(); - } - - // docs:start:private_burn_interface - pub fn burn(self: Self, context: &mut PrivateContext, from: AztecAddress, amount: Field, nonce: Field) { - let _return_values = context.call_private_function( - self.address, - FunctionSelector::from_signature("burn((Field),Field,Field)"), - [from.to_field(), amount, nonce] - ); - } - // docs:end:private_burn_interface -} -// docs:end:token_bridge_token_interface diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index 7924299b27c7..7978fe76412f 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -168,12 +168,7 @@ contract Token { #[aztec(private)] fn privately_mint_private_note(amount: Field) { storage.balances.add(context.msg_sender(), U128::from_integer(amount)); - let selector = FunctionSelector::from_signature("assert_minter_and_mint((Field),Field)"); - let _void = context.call_public_function( - context.this_address(), - selector, - [context.msg_sender().to_field(), amount] - ); + Token::at(context.this_address()).assert_minter_and_mint(context.msg_sender(), amount).enqueue(&mut context); } #[aztec(public)] @@ -277,8 +272,7 @@ contract Token { storage.balances.sub(from, U128::from_integer(amount)); - let selector = FunctionSelector::from_signature("_increase_public_balance((Field),Field)"); - let _void = context.call_public_function(context.this_address(), selector, [to.to_field(), amount]); + Token::at(context.this_address())._increase_public_balance(to, amount).enqueue(&mut context); } // docs:end:unshield @@ -312,8 +306,7 @@ contract Token { storage.balances.sub(from, U128::from_integer(amount)); - let selector = FunctionSelector::from_signature("_reduce_total_supply(Field)"); - let _void = context.call_public_function(context.this_address(), selector, [amount]); + Token::at(context.this_address())._reduce_total_supply(amount).enqueue(&mut context); } // docs:end:burn diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/Nargo.toml b/noir-projects/noir-contracts/contracts/uniswap_contract/Nargo.toml index cabd23e359e7..dbc2b0cf06de 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/Nargo.toml +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/Nargo.toml @@ -7,3 +7,5 @@ type = "contract" [dependencies] aztec = { path = "../../../aztec-nr/aztec" } authwit = { path = "../../../aztec-nr/authwit" } +token = { path = "../token_contract" } +token_bridge = { path = "../token_bridge_contract" } \ No newline at end of file diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/interfaces.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/interfaces.nr deleted file mode 100644 index cd68492fabb0..000000000000 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/interfaces.nr +++ /dev/null @@ -1,80 +0,0 @@ -// docs:start:interfaces -use dep::aztec::prelude::{FunctionSelector, AztecAddress, EthAddress, PrivateContext, Deserialize}; -use dep::aztec::context::{PublicContext, gas::GasOpts}; - -struct Token { - address: AztecAddress, -} - -impl Token { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - pub fn transfer_public( - self: Self, - context: &mut PublicContext, - from: AztecAddress, - to: AztecAddress, - amount: Field, - nonce: Field - ) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("transfer_public((Field),(Field),Field,Field)"), - [from.to_field(), to.to_field(), amount, nonce], - GasOpts::default() - ).assert_empty(); - } - - pub fn unshield( - self: Self, - context: &mut PrivateContext, - from: AztecAddress, - to: AztecAddress, - amount: Field, - nonce: Field - ) { - let _ret = context.call_private_function( - self.address, - FunctionSelector::from_signature("unshield((Field),(Field),Field,Field)"), - [from.to_field(), to.to_field(), amount, nonce] - ); - } -} - -struct TokenBridge { - address: AztecAddress, -} - -impl TokenBridge { - pub fn at(address: AztecAddress) -> Self { - Self { address } - } - - pub fn token(self: Self, context: &mut PublicContext) -> AztecAddress { - context.call_public_function( - self.address, - FunctionSelector::from_signature("get_token()"), - [], - GasOpts::default() - ).deserialize_into() - } - - pub fn exit_to_l1_public( - self: Self, - context: &mut PublicContext, - recipient: EthAddress, - amount: Field, - caller_on_l1: EthAddress, - nonce: Field - ) { - context.call_public_function( - self.address, - FunctionSelector::from_signature("exit_to_l1_public((Field),Field,(Field),Field)"), - [recipient.to_field(), amount, caller_on_l1.to_field(), nonce], - GasOpts::default() - ).assert_empty(); - } -} -// docs:end:interfaces diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr index a595616248e6..32a89fcc704a 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -1,5 +1,4 @@ // docs:start:uniswap_setup -mod interfaces; mod util; // Demonstrates how to use portal contracts to swap on L1 Uniswap with funds on L2 @@ -15,7 +14,8 @@ contract Uniswap { compute_outer_authwit_hash }; - use crate::interfaces::{Token, TokenBridge}; + use dep::token::Token; + use dep::token_bridge::TokenBridge; use crate::util::{compute_swap_private_content_hash, compute_swap_public_content_hash}; #[aztec(storage)] @@ -51,25 +51,18 @@ contract Uniswap { assert_current_call_valid_authwit_public(&mut context, sender); } - let input_asset = TokenBridge::at(input_asset_bridge).token(&mut context); + let input_asset = TokenBridge::at(input_asset_bridge).get_token().call(&mut context); // Transfer funds to this contract Token::at(input_asset).transfer_public( - &mut context, sender, context.this_address(), input_amount, nonce_for_transfer_approval - ); + ).call(&mut context); // Approve bridge to burn this contract's funds and exit to L1 Uniswap Portal - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("_approve_bridge_and_exit_input_asset_to_L1((Field),(Field),Field)"), - [input_asset.to_field(), input_asset_bridge.to_field(), input_amount], - GasOpts::default() - ).assert_empty(); - + Uniswap::at(context.this_address())._approve_bridge_and_exit_input_asset_to_L1(input_asset, input_asset_bridge, input_amount).call(&mut context); // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. let input_asset_bridge_portal_address = get_portal_address(input_asset_bridge); @@ -115,27 +108,18 @@ contract Uniswap { ) { // Assert that user provided token address is same as expected by token bridge. // we can't directly use `input_asset_bridge.token` because that is a public method and public can't return data to private - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("_assert_token_is_same((Field),(Field))"), - [input_asset.to_field(), input_asset_bridge.to_field()] - ); + Uniswap::at(context.this_address())._assert_token_is_same(input_asset, input_asset_bridge).enqueue(&mut context); // Transfer funds to this contract Token::at(input_asset).unshield( - &mut context, context.msg_sender(), context.this_address(), input_amount, nonce_for_unshield_approval - ); + ).call(&mut context); // Approve bridge to burn this contract's funds and exit to L1 Uniswap Portal - context.call_public_function( - context.this_address(), - FunctionSelector::from_signature("_approve_bridge_and_exit_input_asset_to_L1((Field),(Field),Field)"), - [input_asset.to_field(), input_asset_bridge.to_field(), input_amount] - ); + Uniswap::at(context.this_address())._approve_bridge_and_exit_input_asset_to_L1(input_asset, input_asset_bridge, input_amount).enqueue(&mut context); // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. @@ -193,7 +177,11 @@ contract Uniswap { // this method is used for both private and public swaps. #[aztec(public)] #[aztec(internal)] - fn _approve_bridge_and_exit_input_asset_to_L1(token: AztecAddress, token_bridge: AztecAddress, amount: Field) { + fn _approve_bridge_and_exit_input_asset_to_L1( + token: AztecAddress, + token_bridge: AztecAddress, + amount: Field + ) { // approve bridge to burn this contract's funds (required when exiting on L1, as it burns funds on L2): let nonce_for_burn_approval = storage.nonce_for_burn_approval.read(); let selector = FunctionSelector::from_signature("burn_public((Field),Field,Field)"); @@ -212,12 +200,11 @@ contract Uniswap { // Exit to L1 Uniswap Portal ! TokenBridge::at(token_bridge).exit_to_l1_public( - &mut context, context.this_portal_address(), amount, context.this_portal_address(), nonce_for_burn_approval - ); + ).call(&mut context) } // docs:end:authwit_uniswap_set @@ -226,7 +213,7 @@ contract Uniswap { #[aztec(internal)] fn _assert_token_is_same(token: AztecAddress, token_bridge: AztecAddress) { assert( - token.eq(TokenBridge::at(token_bridge).token(&mut context)), "input_asset address is not the same as seen in the bridge contract" + token.eq(TokenBridge::at(token_bridge).get_token().call(&mut context)), "input_asset address is not the same as seen in the bridge contract" ); } // docs:end:assert_token_is_same diff --git a/noir-projects/noir-protocol-circuits/Nargo.toml b/noir-projects/noir-protocol-circuits/Nargo.toml index d3f3c3d55b0c..48cc2fc96f66 100644 --- a/noir-projects/noir-protocol-circuits/Nargo.toml +++ b/noir-projects/noir-protocol-circuits/Nargo.toml @@ -22,6 +22,7 @@ members = [ "crates/public-kernel-teardown-simulated", "crates/public-kernel-tail", "crates/public-kernel-tail-simulated", + "crates/reset-kernel-lib", "crates/rollup-lib", "crates/rollup-merge", "crates/rollup-base", diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/common.nr index bf4f3b8a0483..7b188057a163 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/common.nr @@ -16,8 +16,8 @@ use dep::types::{ MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL }, hash::{ - compute_l2_to_l1_hash, compute_logs_hash, private_functions_root_from_siblings, silo_note_hash, - silo_nullifier, stdlib_recursion_verification_key_compress_native_vk + compute_l2_to_l1_hash, pedersen_hash, private_functions_root_from_siblings, + silo_note_hash, silo_nullifier, stdlib_recursion_verification_key_compress_native_vk, }, merkle_tree::check_membership, utils::{arrays::{array_length, array_to_bounded_vec, validate_array}}, @@ -37,7 +37,8 @@ pub fn validate_arrays(app_public_inputs: PrivateCircuitPublicInputs) { validate_array(app_public_inputs.private_call_stack_hashes); validate_array(app_public_inputs.public_call_stack_hashes); validate_array(app_public_inputs.new_l2_to_l1_msgs); - // encrypted_logs_hash and unencrypted_logs_hash have their own integrity checks. + validate_array(app_public_inputs.encrypted_logs_hashes); + validate_array(app_public_inputs.unencrypted_logs_hashes); } // Validate all read requests against the historical note hash tree root. @@ -106,8 +107,8 @@ pub fn initialize_end_values( public_inputs.end.public_call_stack = array_to_bounded_vec(start.public_call_stack); public_inputs.end.new_l2_to_l1_msgs = array_to_bounded_vec(start.new_l2_to_l1_msgs); - public_inputs.end.encrypted_logs_hash = start.encrypted_logs_hash; - public_inputs.end.unencrypted_logs_hash = start.unencrypted_logs_hash; + public_inputs.end.encrypted_logs_hashes = array_to_bounded_vec(start.encrypted_logs_hashes); + public_inputs.end.unencrypted_logs_hashes = array_to_bounded_vec(start.unencrypted_logs_hashes); public_inputs.end.encrypted_log_preimages_length = start.encrypted_log_preimages_length; public_inputs.end.unencrypted_log_preimages_length = start.unencrypted_log_preimages_length; @@ -287,16 +288,13 @@ pub fn update_end_values( } } public_inputs.end.new_l2_to_l1_msgs.extend_from_bounded_vec(new_l2_to_l1_msgs_to_insert); - + // logs hashes // See the following thread if not clear: // https://discourse.aztec.network/t/proposal-forcing-the-sequencer-to-actually-submit-data-to-l1/426 - let previous_encrypted_logs_hash = public_inputs.end.encrypted_logs_hash; - let current_encrypted_logs_hash = private_call_public_inputs.encrypted_logs_hash; - public_inputs.end.encrypted_logs_hash = compute_logs_hash(previous_encrypted_logs_hash,current_encrypted_logs_hash); - let previous_unencrypted_logs_hash = public_inputs.end.unencrypted_logs_hash; - let current_unencrypted_logs_hash = private_call_public_inputs.unencrypted_logs_hash; - public_inputs.end.unencrypted_logs_hash = compute_logs_hash(previous_unencrypted_logs_hash,current_unencrypted_logs_hash); + + public_inputs.end.encrypted_logs_hashes.extend_from_bounded_vec(array_to_bounded_vec(private_call_public_inputs.encrypted_logs_hashes)); + public_inputs.end.unencrypted_logs_hashes.extend_from_bounded_vec(array_to_bounded_vec(private_call_public_inputs.unencrypted_logs_hashes)); // Add log preimages lengths from current iteration to accumulated lengths public_inputs.end.encrypted_log_preimages_length = public_inputs.end.encrypted_log_preimages_length + diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/kernel_circuit_public_inputs_composer.nr index 22a31568e9bb..84157b9b95bc 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/kernel_circuit_public_inputs_composer.nr @@ -10,7 +10,8 @@ use dep::types::{ constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, + MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX }, grumpkin_private_key::GrumpkinPrivateKey, hash::{compute_note_hash_nonce, compute_unique_siloed_note_hash}, @@ -29,6 +30,10 @@ struct KernelCircuitPublicInputsComposer { sorted_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], sorted_nullifiers_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX], transient_note_hash_index_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX], + sorted_encrypted_log_hashes: [SideEffect; MAX_ENCRYPTED_LOGS_PER_TX], + sorted_encrypted_log_hashes_indexes: [u64; MAX_ENCRYPTED_LOGS_PER_TX], + sorted_unencrypted_log_hashes: [SideEffect; MAX_UNENCRYPTED_LOGS_PER_TX], + sorted_unencrypted_log_hashes_indexes: [u64; MAX_UNENCRYPTED_LOGS_PER_TX], } impl KernelCircuitPublicInputsComposer { @@ -38,7 +43,11 @@ impl KernelCircuitPublicInputsComposer { sorted_note_hashes_indexes: [u64; MAX_NEW_NOTE_HASHES_PER_TX], sorted_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], sorted_nullifiers_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX], - transient_note_hash_index_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX] + transient_note_hash_index_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX], + sorted_encrypted_log_hashes: [SideEffect; MAX_ENCRYPTED_LOGS_PER_TX], + sorted_encrypted_log_hashes_indexes: [u64; MAX_ENCRYPTED_LOGS_PER_TX], + sorted_unencrypted_log_hashes: [SideEffect; MAX_UNENCRYPTED_LOGS_PER_TX], + sorted_unencrypted_log_hashes_indexes: [u64; MAX_UNENCRYPTED_LOGS_PER_TX], ) -> Self { let public_inputs = PrivateKernelCircuitPublicInputsBuilder::empty(); @@ -49,7 +58,11 @@ impl KernelCircuitPublicInputsComposer { sorted_note_hashes_indexes, sorted_nullifiers, sorted_nullifiers_indexes, - transient_note_hash_index_hints + transient_note_hash_index_hints, + sorted_encrypted_log_hashes, + sorted_encrypted_log_hashes_indexes, + sorted_unencrypted_log_hashes, + sorted_unencrypted_log_hashes_indexes, } } @@ -136,10 +149,23 @@ impl KernelCircuitPublicInputsComposer { ); self.public_inputs.end.new_nullifiers = array_to_bounded_vec(self.sorted_nullifiers); + assert_sorted_array( + accumulated_data.encrypted_logs_hashes, + self.sorted_encrypted_log_hashes, + self.sorted_encrypted_log_hashes_indexes, + asc_sort_by_counters + ); + self.public_inputs.end.encrypted_logs_hashes = array_to_bounded_vec(self.sorted_encrypted_log_hashes); + + assert_sorted_array( + accumulated_data.unencrypted_logs_hashes, + self.sorted_unencrypted_log_hashes, + self.sorted_unencrypted_log_hashes_indexes, + asc_sort_by_counters + ); + self.public_inputs.end.unencrypted_logs_hashes = array_to_bounded_vec(self.sorted_unencrypted_log_hashes); // TODO: Sort all the side effects below. self.public_inputs.end.new_l2_to_l1_msgs = array_to_bounded_vec(accumulated_data.new_l2_to_l1_msgs); - self.public_inputs.end.encrypted_logs_hash = accumulated_data.encrypted_logs_hash; - self.public_inputs.end.unencrypted_logs_hash = accumulated_data.unencrypted_logs_hash; self.public_inputs.end.encrypted_log_preimages_length = accumulated_data.encrypted_log_preimages_length; self.public_inputs.end.unencrypted_log_preimages_length = accumulated_data.unencrypted_log_preimages_length; } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index 84e68d19d10a..3c6784bdc6be 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -22,7 +22,7 @@ impl PrivateKernelInitCircuitPrivateInputs { public_inputs.constants = CombinedConstantData { historical_header: self.private_call.call_stack_item.public_inputs.historical_header, tx_context: self.tx_request.tx_context, - gas_settings: GasSettings::empty(), // TODO(palla/gas-in-circuits) + gas_settings: self.tx_request.gas_settings, }; public_inputs.min_revertible_side_effect_counter = self.private_call.call_stack_item.public_inputs.min_revertible_side_effect_counter; } @@ -123,7 +123,7 @@ mod tests { address::{AztecAddress, EthAddress, compute_initialization_hash}, constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, grumpkin_point::GrumpkinPoint, grumpkin_private_key::GrumpkinPrivateKey, - hash::{compute_logs_hash, stdlib_recursion_verification_key_compress_native_vk}, + hash::stdlib_recursion_verification_key_compress_native_vk, messaging::l2_to_l1_message::L2ToL1Message, tests::private_call_data_builder::PrivateCallDataBuilder, transaction::tx_request::TxRequest, utils::arrays::array_length @@ -158,12 +158,14 @@ mod tests { let mut builder = PrivateKernelInitInputsBuilder::new(); // Logs for the private call. - let encrypted_logs_hash = 16; - let encrypted_log_preimages_length = 100; - let unencrypted_logs_hash = 26; - let unencrypted_log_preimages_length = 50; - builder.private_call.set_encrypted_logs(encrypted_logs_hash, encrypted_log_preimages_length); - builder.private_call.set_unencrypted_logs(unencrypted_logs_hash, unencrypted_log_preimages_length); + let encrypted_logs_hashes = [16, 36]; + let encrypted_log_preimages_length = [100, 75]; + let unencrypted_logs_hashes = [26, 46]; + let unencrypted_log_preimages_length = [50, 25]; + builder.private_call.set_encrypted_logs(encrypted_logs_hashes[0], encrypted_log_preimages_length[0]); + builder.private_call.set_unencrypted_logs(unencrypted_logs_hashes[0], unencrypted_log_preimages_length[0]); + builder.private_call.set_encrypted_logs(encrypted_logs_hashes[1], encrypted_log_preimages_length[1]); + builder.private_call.set_unencrypted_logs(unencrypted_logs_hashes[1], unencrypted_log_preimages_length[1]); let public_inputs = builder.execute(); @@ -172,15 +174,12 @@ mod tests { assert_eq(public_inputs.end.new_nullifiers[0].value, tx_hash); // Log preimages length should increase by `(un)encrypted_log_preimages_length` from private input - assert_eq(public_inputs.end.encrypted_log_preimages_length, encrypted_log_preimages_length); - assert_eq(public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length); - - // Logs hashes should be a sha256 hash of a 0 value (the previous log hash) and the `(un)encrypted_logs_hash` from private input - let expected_encrypted_logs_hash = compute_logs_hash(0, encrypted_logs_hash); - assert_eq(public_inputs.end.encrypted_logs_hash, expected_encrypted_logs_hash); - - let expected_unencrypted_logs_hash = compute_logs_hash(0, unencrypted_logs_hash); - assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); + assert_eq(public_inputs.end.encrypted_log_preimages_length, encrypted_log_preimages_length.reduce(|a, b| a + b)); + assert_eq(public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length.reduce(|a, b| a + b)); + assert_eq(public_inputs.end.encrypted_logs_hashes[0].value, encrypted_logs_hashes[0]); + assert_eq(public_inputs.end.unencrypted_logs_hashes[0].value, unencrypted_logs_hashes[0]); + assert_eq(public_inputs.end.encrypted_logs_hashes[1].value, encrypted_logs_hashes[1]); + assert_eq(public_inputs.end.unencrypted_logs_hashes[1].value, unencrypted_logs_hashes[1]); } #[test(should_fail_with = "invalid array")] @@ -257,6 +256,20 @@ mod tests { builder.failed(); } + #[test(should_fail_with = "invalid array")] + fn input_validation_malformed_arrays_logs() { + let mut builder = PrivateKernelInitInputsBuilder::new(); + + builder.private_call.public_inputs.encrypted_logs_hashes.extend_from_array( + [ + SideEffect { value: 0, counter: 0 }, + SideEffect { value: 9123, counter: 1 } + ] + ); + + builder.failed(); + } + #[test(should_fail_with="Private kernel circuit can only execute a private function")] fn private_function_is_private_false_fails() { let mut builder = PrivateKernelInitInputsBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index d87964fc9ef9..03425d36d98b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -68,7 +68,7 @@ mod tests { kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, max_block_number::MaxBlockNumber, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, - address::{AztecAddress, EthAddress}, hash::compute_logs_hash, + address::{AztecAddress, EthAddress}, messaging::l2_to_l1_message::L2ToL1Message, utils::{arrays::array_length}, tests::{private_call_data_builder::PrivateCallDataBuilder, fixture_builder::FixtureBuilder} }; @@ -447,6 +447,20 @@ mod tests { builder.failed(); } + #[test(should_fail_with = "invalid array")] + fn input_validation_malformed_arrays_logs() { + let mut builder = PrivateKernelInnerInputsBuilder::new(); + + builder.private_call.public_inputs.encrypted_logs_hashes.extend_from_array( + [ + SideEffect { value: 0, counter: 0 }, + SideEffect { value: 9123, counter: 1 } + ] + ); + + builder.failed(); + } + #[test(should_fail_with = "extend_from_bounded_vec out of bounds")] fn private_kernel_should_fail_if_aggregating_too_many_commitments() { let mut builder = PrivateKernelInnerInputsBuilder::new(); @@ -642,7 +656,7 @@ mod tests { } #[test] - fn native_logs_are_hashed_as_expected() { + fn native_logs_are_set_as_expected() { let mut builder = PrivateKernelInnerInputsBuilder::new(); // Logs for the current call stack. @@ -673,11 +687,10 @@ mod tests { public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length ); - let expected_encrypted_logs_hash = compute_logs_hash(prev_encrypted_logs_hash, encrypted_logs_hash); - assert_eq(public_inputs.end.encrypted_logs_hash, expected_encrypted_logs_hash); - - let expected_unencrypted_logs_hash = compute_logs_hash(prev_unencrypted_logs_hash, unencrypted_logs_hash); - assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); + assert_eq(public_inputs.end.encrypted_logs_hashes[0].value, prev_encrypted_logs_hash); + assert_eq(public_inputs.end.unencrypted_logs_hashes[0].value, prev_unencrypted_logs_hash); + assert_eq(public_inputs.end.encrypted_logs_hashes[1].value, encrypted_logs_hash); + assert_eq(public_inputs.end.unencrypted_logs_hashes[1].value, unencrypted_logs_hash); } #[test(should_fail_with="new_note_hashes must be empty for static calls")] diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr index ac229a9beb90..5d360bb00241 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -7,7 +7,7 @@ use dep::types::{ }, constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX + MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX }, grumpkin_private_key::GrumpkinPrivateKey, utils::arrays::array_length }; @@ -21,6 +21,10 @@ struct PrivateKernelTailCircuitPrivateInputs { sorted_new_nullifiers_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX], nullifier_read_request_hints: NullifierReadRequestHints, nullifier_commitment_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX], + sorted_encrypted_log_hashes: [SideEffect; MAX_ENCRYPTED_LOGS_PER_TX], + sorted_encrypted_log_hashes_indexes: [u64; MAX_ENCRYPTED_LOGS_PER_TX], + sorted_unencrypted_log_hashes: [SideEffect; MAX_UNENCRYPTED_LOGS_PER_TX], + sorted_unencrypted_log_hashes_indexes: [u64; MAX_UNENCRYPTED_LOGS_PER_TX], master_nullifier_secret_keys: [GrumpkinPrivateKey; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], } @@ -49,7 +53,11 @@ impl PrivateKernelTailCircuitPrivateInputs { self.sorted_new_note_hashes_indexes, self.sorted_new_nullifiers, self.sorted_new_nullifiers_indexes, - self.nullifier_commitment_hints + self.nullifier_commitment_hints, + self.sorted_encrypted_log_hashes, + self.sorted_encrypted_log_hashes_indexes, + self.sorted_unencrypted_log_hashes, + self.sorted_unencrypted_log_hashes_indexes, ); composer.compose().finish() } @@ -59,7 +67,7 @@ mod tests { use crate::private_kernel_tail::PrivateKernelTailCircuitPrivateInputs; use dep::reset_kernel_lib::{ tests::nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder, - read_request_reset::{PendingReadHint, ReadRequestState, ReadRequestStatus} + reset::read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus} }; use dep::types::constants::{ MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, @@ -71,7 +79,7 @@ mod tests { side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} }, grumpkin_private_key::GrumpkinPrivateKey, - hash::{compute_note_hash_nonce, compute_unique_siloed_note_hash}, + hash::{compute_note_hash_nonce, compute_unique_siloed_note_hash, accumulate_sha256}, tests::{fixture_builder::FixtureBuilder, sort::sort_get_sorted_hints}, utils::{arrays::{array_eq, array_length}}, traits::{Empty, is_empty, is_empty_array} }; @@ -154,6 +162,20 @@ mod tests { sorted_nullifier_commitment_hints[i] = sorted_new_nullifiers_indexes[self.nullifier_commitment_hints[i]]; } + let sorted = sort_get_sorted_hints( + self.previous_kernel.encrypted_logs_hashes.storage, + |a: SideEffect, b: SideEffect| a.counter < b.counter + ); + let sorted_encrypted_log_hashes = sorted.sorted_array; + let sorted_encrypted_log_hashes_indexes = sorted.sorted_index_hints; + + let sorted = sort_get_sorted_hints( + self.previous_kernel.unencrypted_logs_hashes.storage, + |a: SideEffect, b: SideEffect| a.counter < b.counter + ); + let sorted_unencrypted_log_hashes = sorted.sorted_array; + let sorted_unencrypted_log_hashes_indexes = sorted.sorted_index_hints; + let kernel = PrivateKernelTailCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_data(), sorted_new_note_hashes, @@ -163,7 +185,11 @@ mod tests { sorted_new_nullifiers_indexes, nullifier_read_request_hints: self.nullifier_read_request_hints_builder.to_hints(), nullifier_commitment_hints: sorted_nullifier_commitment_hints, - master_nullifier_secret_keys: [GrumpkinPrivateKey::empty(); MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX] + sorted_encrypted_log_hashes, + sorted_encrypted_log_hashes_indexes, + sorted_unencrypted_log_hashes, + sorted_unencrypted_log_hashes_indexes, + master_nullifier_secret_keys: [GrumpkinPrivateKey::empty(); MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], }; kernel.native_private_kernel_circuit_tail() } @@ -177,6 +203,14 @@ mod tests { } } + #[test] + unconstrained fn execution_succeeded() { + let mut builder = PrivateKernelTailInputsBuilder::new(); + let public_inputs = builder.execute(); + + assert(is_empty(public_inputs.start_state)); + } + #[test] unconstrained fn native_matching_one_read_request_to_commitment_works() { let mut builder = PrivateKernelTailInputsBuilder::new(); @@ -211,6 +245,38 @@ mod tests { assert_eq(public_inputs.rollup_validation_requests.max_block_number.unwrap(), 13); } + #[test] + fn logs_are_handled_as_expected() { + let mut builder = PrivateKernelTailInputsBuilder::new(); + // Logs for the previous call stack. + let prev_encrypted_logs_hash = 80; + let prev_encrypted_log_preimages_length = 13; + let prev_unencrypted_logs_hash = 956; + let prev_unencrypted_log_preimages_length = 24; + builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.set_unencrypted_logs( + prev_unencrypted_logs_hash, + prev_unencrypted_log_preimages_length + ); + // Logs for the current call stack. + let unencrypted_logs_hash = 26; + let unencrypted_log_preimages_length = 50; + builder.previous_kernel.set_unencrypted_logs(unencrypted_logs_hash, unencrypted_log_preimages_length); + + let public_inputs = builder.execute(); + + assert_eq(public_inputs.end.encrypted_log_preimages_length, prev_encrypted_log_preimages_length); + assert_eq( + public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length + ); + + let expected_encrypted_logs_hash = accumulate_sha256([0, prev_encrypted_logs_hash]); + assert_eq(public_inputs.end.encrypted_logs_hash, expected_encrypted_logs_hash); + let mut expected_unencrypted_logs_hash = accumulate_sha256([0, prev_unencrypted_logs_hash]); + expected_unencrypted_logs_hash = accumulate_sha256([expected_unencrypted_logs_hash, unencrypted_logs_hash]); + assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); + } + #[test] unconstrained fn one_pending_nullifier_read_request() { let mut builder = PrivateKernelTailInputsBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr index d3569bdf3b5f..081219df963b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr @@ -7,7 +7,7 @@ use dep::types::{ }, constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX + MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX }, grumpkin_private_key::GrumpkinPrivateKey, utils::arrays::array_length }; @@ -21,6 +21,10 @@ struct PrivateKernelTailToPublicCircuitPrivateInputs { sorted_new_nullifiers_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX], nullifier_read_request_hints: NullifierReadRequestHints, nullifier_commitment_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX], + sorted_encrypted_log_hashes: [SideEffect; MAX_ENCRYPTED_LOGS_PER_TX], + sorted_encrypted_log_hashes_indexes: [u64; MAX_ENCRYPTED_LOGS_PER_TX], + sorted_unencrypted_log_hashes: [SideEffect; MAX_UNENCRYPTED_LOGS_PER_TX], + sorted_unencrypted_log_hashes_indexes: [u64; MAX_UNENCRYPTED_LOGS_PER_TX], master_nullifier_secret_keys: [GrumpkinPrivateKey; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], } @@ -49,7 +53,11 @@ impl PrivateKernelTailToPublicCircuitPrivateInputs { self.sorted_new_note_hashes_indexes, self.sorted_new_nullifiers, self.sorted_new_nullifiers_indexes, - self.nullifier_commitment_hints + self.nullifier_commitment_hints, + self.sorted_encrypted_log_hashes, + self.sorted_encrypted_log_hashes_indexes, + self.sorted_unencrypted_log_hashes, + self.sorted_unencrypted_log_hashes_indexes, ); composer.compose_public().finish_to_public() } @@ -59,7 +67,7 @@ mod tests { use crate::private_kernel_tail_to_public::PrivateKernelTailToPublicCircuitPrivateInputs; use dep::reset_kernel_lib::{ tests::nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder, - read_request_reset::{PendingReadHint, ReadRequestState, ReadRequestStatus} + reset::read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus} }; use dep::types::constants::{ MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, @@ -161,6 +169,20 @@ mod tests { sorted_nullifier_commitment_hints[i] = sorted_new_nullifiers_indexes[self.nullifier_commitment_hints[i]]; } + let sorted = sort_get_sorted_hints( + self.previous_kernel.encrypted_logs_hashes.storage, + |a: SideEffect, b: SideEffect| a.counter < b.counter + ); + let sorted_encrypted_log_hashes = sorted.sorted_array; + let sorted_encrypted_log_hashes_indexes = sorted.sorted_index_hints; + + let sorted = sort_get_sorted_hints( + self.previous_kernel.unencrypted_logs_hashes.storage, + |a: SideEffect, b: SideEffect| a.counter < b.counter + ); + let sorted_unencrypted_log_hashes = sorted.sorted_array; + let sorted_unencrypted_log_hashes_indexes = sorted.sorted_index_hints; + let kernel = PrivateKernelTailToPublicCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_data(), sorted_new_note_hashes, @@ -170,6 +192,10 @@ mod tests { sorted_new_nullifiers_indexes, nullifier_read_request_hints: self.nullifier_read_request_hints_builder.to_hints(), nullifier_commitment_hints: sorted_nullifier_commitment_hints, + sorted_encrypted_log_hashes, + sorted_encrypted_log_hashes_indexes, + sorted_unencrypted_log_hashes, + sorted_unencrypted_log_hashes_indexes, master_nullifier_secret_keys: [GrumpkinPrivateKey::empty(); MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], }; kernel.execute() diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/common.nr index 1008e0c0f49a..b9d428ecd6ce 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/common.nr @@ -12,7 +12,7 @@ use dep::types::{ MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, - MAX_PUBLIC_DATA_READS_PER_CALL + MAX_PUBLIC_DATA_READS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL }, hash::{silo_note_hash, silo_nullifier, compute_l2_to_l1_hash, accumulate_sha256}, utils::{arrays::{array_length, array_to_bounded_vec}}, traits::{is_empty, is_empty_array} @@ -63,9 +63,9 @@ pub fn initialize_emitted_end_values( circuit_outputs.end.new_nullifiers = array_to_bounded_vec(start.new_nullifiers); circuit_outputs.end.new_l2_to_l1_msgs = array_to_bounded_vec(start.new_l2_to_l1_msgs); circuit_outputs.end.public_data_update_requests = array_to_bounded_vec(start.public_data_update_requests); - circuit_outputs.end.unencrypted_logs_hash = start.unencrypted_logs_hash; + circuit_outputs.end.unencrypted_logs_hashes = array_to_bounded_vec(start.unencrypted_logs_hashes); circuit_outputs.end.unencrypted_log_preimages_length = start.unencrypted_log_preimages_length; - circuit_outputs.end.encrypted_logs_hash = start.encrypted_logs_hash; + circuit_outputs.end.encrypted_logs_hashes = array_to_bounded_vec(start.encrypted_logs_hashes); circuit_outputs.end.encrypted_log_preimages_length = start.encrypted_log_preimages_length; } @@ -74,16 +74,13 @@ pub fn initialize_emitted_end_values( circuit_outputs.end_non_revertible.new_nullifiers = array_to_bounded_vec(start_non_revertible.new_nullifiers); circuit_outputs.end_non_revertible.new_l2_to_l1_msgs = array_to_bounded_vec(start_non_revertible.new_l2_to_l1_msgs); circuit_outputs.end_non_revertible.public_data_update_requests = array_to_bounded_vec(start_non_revertible.public_data_update_requests); - circuit_outputs.end_non_revertible.unencrypted_logs_hash = start_non_revertible.unencrypted_logs_hash; + circuit_outputs.end_non_revertible.unencrypted_logs_hashes = array_to_bounded_vec(start_non_revertible.unencrypted_logs_hashes); circuit_outputs.end_non_revertible.unencrypted_log_preimages_length = start_non_revertible.unencrypted_log_preimages_length; - circuit_outputs.end_non_revertible.encrypted_logs_hash = start_non_revertible.encrypted_logs_hash; + circuit_outputs.end_non_revertible.encrypted_logs_hashes = array_to_bounded_vec(start_non_revertible.encrypted_logs_hashes); circuit_outputs.end_non_revertible.encrypted_log_preimages_length = start_non_revertible.encrypted_log_preimages_length; - // TODO - should be propagated only in initialize_end_values() and clear them in the tail circuit. The - // max_block_number must be propagated to the rollup however as a RollupValidationRequest. let start = previous_kernel.public_inputs.validation_requests; circuit_outputs.validation_requests.max_block_number = start.for_rollup.max_block_number; - circuit_outputs.validation_requests.public_data_reads = array_to_bounded_vec(start.public_data_reads); } // Initialises the circuit outputs with the end state of the previous iteration. @@ -94,6 +91,10 @@ pub fn initialize_end_values( ) { initialize_emitted_end_values(previous_kernel, circuit_outputs); + // Copy gas-used as-is. Gas used in this iteration will be deducted later in update_(non)_revertible_gas_used. + circuit_outputs.end.gas_used = previous_kernel.public_inputs.end.gas_used; + circuit_outputs.end_non_revertible.gas_used = previous_kernel.public_inputs.end_non_revertible.gas_used; + if circuit_outputs.revert_code == 0 { let start = previous_kernel.public_inputs.end; circuit_outputs.end.public_call_stack = array_to_bounded_vec(start.public_call_stack); @@ -106,6 +107,7 @@ pub fn initialize_end_values( circuit_outputs.validation_requests.max_block_number = previous_kernel.public_inputs.validation_requests.for_rollup.max_block_number; circuit_outputs.validation_requests.nullifier_read_requests = array_to_bounded_vec(start.nullifier_read_requests); circuit_outputs.validation_requests.nullifier_non_existent_read_requests = array_to_bounded_vec(start.nullifier_non_existent_read_requests); + circuit_outputs.validation_requests.public_data_reads = array_to_bounded_vec(start.public_data_reads); } fn perform_static_call_checks(public_call: PublicCallData) { @@ -169,6 +171,60 @@ pub fn update_validation_requests(public_call: PublicCallData, circuit_outputs: propagate_valid_public_data_reads(public_call, circuit_outputs); } +pub fn update_revertible_gas_used(public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder) { + let tx_gas_limits = circuit_outputs.constants.gas_settings.get_gas_limits(); + let call_gas_left = public_call.call_stack_item.public_inputs.gas_left; + let accum_end_non_revertible_gas_used = circuit_outputs.end_non_revertible.gas_used; + + // dep::types::debug_log::debug_log_format( + // "Updating revertible gas: limit.da={0} limit.l1={1} limit.l2={2} left.da={3} left.l1={4} left.l2={5} used.da={6} used.l1={7} used.l2={8}", + // [ + // tx_gas_limits.da_gas as Field, + // tx_gas_limits.l1_gas as Field, + // tx_gas_limits.l2_gas as Field, + // call_gas_left.da_gas as Field, + // call_gas_left.l1_gas as Field, + // call_gas_left.l2_gas as Field, + // accum_end_non_revertible_gas_used.da_gas as Field, + // accum_end_non_revertible_gas_used.l1_gas as Field, + // accum_end_non_revertible_gas_used.l2_gas as Field + // ] + // ); + + circuit_outputs.end.gas_used = tx_gas_limits + .sub(call_gas_left) + .sub(accum_end_non_revertible_gas_used); +} + +pub fn update_non_revertible_gas_used(public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder) { + let tx_gas_limits = circuit_outputs.constants.gas_settings.get_gas_limits(); + let call_gas_left = public_call.call_stack_item.public_inputs.gas_left; + let accum_end_gas_used = circuit_outputs.end.gas_used; + + // dep::types::debug_log::debug_log_format( + // "Updating non-revertible gas: limit.da={0} limit.l1={1} limit.l2={2} left.da={3} left.l1={4} left.l2={5} used.da={6} used.l1={7} used.l2={8}", + // [ + // tx_gas_limits.da_gas as Field, + // tx_gas_limits.l1_gas as Field, + // tx_gas_limits.l2_gas as Field, + // call_gas_left.da_gas as Field, + // call_gas_left.l1_gas as Field, + // call_gas_left.l2_gas as Field, + // accum_end_gas_used.da_gas as Field, + // accum_end_gas_used.l1_gas as Field, + // accum_end_gas_used.l2_gas as Field + // ] + // ); + + // println( + // f"Updating non-revertible gas: tx_gas_limits={tx_gas_limits} call_gas_left={call_gas_left} accum_end_gas_used={accum_end_gas_used}" + // ); + + circuit_outputs.end_non_revertible.gas_used = tx_gas_limits + .sub(call_gas_left) + .sub(accum_end_gas_used); +} + pub fn update_public_end_non_revertible_values( public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder @@ -186,7 +242,8 @@ pub fn update_public_end_non_revertible_values( propagate_new_nullifiers_non_revertible(public_call, circuit_outputs); propagate_new_note_hashes_non_revertible(public_call, circuit_outputs); - propagate_new_l2_to_l1_messages(public_call, circuit_outputs); + propagate_new_l2_to_l1_messages_non_revertible(public_call, circuit_outputs); + propagate_new_unencrypted_logs_non_revertible(public_call, circuit_outputs); propagate_valid_non_revertible_public_data_update_requests(public_call, circuit_outputs); } @@ -206,7 +263,7 @@ pub fn update_public_end_values(public_call: PublicCallData, circuit_outputs: &m propagate_new_note_hashes(public_call, circuit_outputs); propagate_new_l2_to_l1_messages(public_call, circuit_outputs); - + propagate_new_unencrypted_logs(public_call, circuit_outputs); propagate_valid_public_data_update_requests(public_call, circuit_outputs); } @@ -399,7 +456,10 @@ fn propagate_new_nullifiers( circuit_outputs.end.new_nullifiers.extend_from_bounded_vec(siloed_new_nullifiers); } -fn propagate_new_l2_to_l1_messages(public_call: PublicCallData, public_inputs: &mut PublicKernelCircuitPublicInputsBuilder) { +fn propagate_new_l2_to_l1_messages_non_revertible( + public_call: PublicCallData, + public_inputs: &mut PublicKernelCircuitPublicInputsBuilder +) { // new l2 to l1 messages let public_call_public_inputs = public_call.call_stack_item.public_inputs; let storage_contract_address = public_call_public_inputs.call_context.storage_contract_address; @@ -418,36 +478,61 @@ fn propagate_new_l2_to_l1_messages(public_call: PublicCallData, public_inputs: & new_l2_to_l1_msgs_to_insert.push(new_l2_to_l1_msgs) } } - public_inputs.end.new_l2_to_l1_msgs.extend_from_bounded_vec(new_l2_to_l1_msgs_to_insert); + public_inputs.end_non_revertible.new_l2_to_l1_msgs.extend_from_bounded_vec(new_l2_to_l1_msgs_to_insert); } -/** - * @brief Accumulates unencrypted logs hashes and lengths. - * @param The type of kernel input - * @param public_kernel_inputs The inputs to this iteration of the kernel circuit - * @param circuit_outputs The circuit outputs to be populated - * @note See the following thread if not clear: - * https://discourse.aztec.network/t/proposal-forcing-the-sequencer-to-actually-submit-data-to-l1/426 - * @note Used by public kernels which had previous iterations. - */ -pub fn accumulate_unencrypted_logs( - public_call: PublicCallData, - previous_unencrypted_logs_hash: Field, - previous_unencrypted_log_preimages_length: Field, - public_inputs: &mut PublicKernelCircuitPublicInputsBuilder -) { +fn propagate_new_l2_to_l1_messages(public_call: PublicCallData, public_inputs: &mut PublicKernelCircuitPublicInputsBuilder) { + // new l2 to l1 messages let public_call_public_inputs = public_call.call_stack_item.public_inputs; + let storage_contract_address = public_call_public_inputs.call_context.storage_contract_address; - let current_unencrypted_logs_hash = public_call_public_inputs.unencrypted_logs_hash; - public_inputs.end.unencrypted_logs_hash = accumulate_sha256([ - previous_unencrypted_logs_hash, - current_unencrypted_logs_hash, - ]); + let new_l2_to_l1_msgs = public_call_public_inputs.new_l2_to_l1_msgs; + let mut new_l2_to_l1_msgs_to_insert : BoundedVec = BoundedVec::new(); + for i in 0..MAX_NEW_L2_TO_L1_MSGS_PER_CALL { + let msg = new_l2_to_l1_msgs[i]; + if !is_empty(msg) { + let new_l2_to_l1_msgs = compute_l2_to_l1_hash( + storage_contract_address, + public_inputs.constants.tx_context.version, + public_inputs.constants.tx_context.chain_id, + msg + ); + new_l2_to_l1_msgs_to_insert.push(new_l2_to_l1_msgs) + } + } + public_inputs.end.new_l2_to_l1_msgs.extend_from_bounded_vec(new_l2_to_l1_msgs_to_insert); +} - // Add log preimages lengths from current iteration to accumulated lengths - let current_unencrypted_log_preimages_length = public_call_public_inputs.unencrypted_log_preimages_length; - public_inputs.end.unencrypted_log_preimages_length = - previous_unencrypted_log_preimages_length + current_unencrypted_log_preimages_length; +pub fn propagate_new_unencrypted_logs(public_call: PublicCallData, public_inputs: &mut PublicKernelCircuitPublicInputsBuilder) { + // new unencrypted logs + let new_logs = public_call.call_stack_item.public_inputs.unencrypted_logs_hashes; + // TODO(Miranda): silo logs here once we have finalised struct + let mut new_logs_to_insert : BoundedVec = BoundedVec::new(); + for i in 0..MAX_UNENCRYPTED_LOGS_PER_CALL { + let new_log = new_logs[i]; + if new_log.value != 0 { + // let siloed_new_log = something; + new_logs_to_insert.push(new_log) + } + } + public_inputs.end.unencrypted_logs_hashes.extend_from_bounded_vec(new_logs_to_insert); + public_inputs.end.unencrypted_log_preimages_length += public_call.call_stack_item.public_inputs.unencrypted_log_preimages_length; +} + +pub fn propagate_new_unencrypted_logs_non_revertible(public_call: PublicCallData, public_inputs: &mut PublicKernelCircuitPublicInputsBuilder) { + // new unencrypted logs + let new_logs = public_call.call_stack_item.public_inputs.unencrypted_logs_hashes; + // TODO(Miranda): silo logs here once we have finalised struct + let mut new_logs_to_insert : BoundedVec = BoundedVec::new(); + for i in 0..MAX_UNENCRYPTED_LOGS_PER_CALL { + let new_log = new_logs[i]; + if new_log.value != 0 { + // let siloed_new_log = something; + new_logs_to_insert.push(new_log) + } + } + public_inputs.end_non_revertible.unencrypted_logs_hashes.extend_from_bounded_vec(new_logs_to_insert); + public_inputs.end_non_revertible.unencrypted_log_preimages_length += public_call.call_stack_item.public_inputs.unencrypted_log_preimages_length; } /** diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr index 05dea2c0e60a..dda4e888bdca 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr @@ -35,17 +35,13 @@ impl PublicKernelAppLogicCircuitPrivateInputs { common::update_validation_requests(self.public_call, &mut public_inputs); + common::update_revertible_gas_used(self.public_call, &mut public_inputs); + if public_inputs.revert_code == 0 { // Pops the item from the call stack and validates it against the current execution. let call_request = public_inputs.end.public_call_stack.pop(); common::validate_call_against_request(self.public_call, call_request); common::update_public_end_values(self.public_call, &mut public_inputs); - common::accumulate_unencrypted_logs( - self.public_call, - self.previous_kernel.public_inputs.end.unencrypted_logs_hash, - self.previous_kernel.public_inputs.end.unencrypted_log_preimages_length, - &mut public_inputs - ); } else { let mut remaining_calls = array_to_bounded_vec(self.previous_kernel.public_inputs.end.public_call_stack); let reverted_call_request = remaining_calls.pop(); @@ -75,12 +71,12 @@ mod tests { }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, public_data_read::PublicDataRead, - public_data_update_request::PublicDataUpdateRequest, read_request::ReadRequest, - side_effect::{SideEffect, SideEffectLinkedToNoteHash} + gas::Gas, kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, + read_request::ReadRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId, - hash::{compute_l2_to_l1_hash, compute_logs_hash, silo_note_hash, silo_nullifier}, + hash::{compute_l2_to_l1_hash, silo_note_hash, silo_nullifier}, messaging::l2_to_l1_message::L2ToL1Message, tests::{fixture_builder::FixtureBuilder, public_call_data_builder::PublicCallDataBuilder}, utils::arrays::{array_eq, array_length} @@ -315,11 +311,9 @@ mod tests { assert_eq( public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length ); - - assert_eq(public_inputs.end.encrypted_logs_hash, prev_encrypted_logs_hash); - - let expected_unencrypted_logs_hash = compute_logs_hash(prev_unencrypted_logs_hash, unencrypted_logs_hash); - assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); + assert_eq(public_inputs.end.encrypted_logs_hashes[0].value, prev_encrypted_logs_hash); + assert_eq(public_inputs.end.unencrypted_logs_hashes[0].value, prev_unencrypted_logs_hash); + assert_eq(public_inputs.end.unencrypted_logs_hashes[1].value, unencrypted_logs_hash); } #[test(should_fail_with="No contract storage update requests are allowed for static calls")] @@ -448,4 +442,28 @@ mod tests { assert_eq(request_context.counter, request_1.counter); assert_eq(request_context.contract_address, storage_contract_address); } + + #[test] + fn updates_revertible_gas_used() { + let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); + + // Transaction gas limit is 1k + builder.previous_kernel.gas_settings.da.gas_limit = 1000; + builder.previous_kernel.gas_settings.l1.gas_limit = 1000; + builder.previous_kernel.gas_settings.l2.gas_limit = 1000; + + // Revertible has already used 300 + builder.previous_kernel.gas_used = Gas::new(300, 300, 300); + + // This call starts with 700 gas left + builder.public_call.public_inputs.call_context.gas_left = Gas::new(700, 700, 700); + + // And uses 200, ending with 500 left + builder.public_call.public_inputs.gas_left = Gas::new(500, 500, 500); + + // So the updated gas used by revertible must go up by 200, and non-revertible must stay the same + let output = builder.execute(); + assert_eq(output.end.gas_used, Gas::new(500, 500, 500)); + assert_eq(output.end_non_revertible.gas_used, Gas::new(0, 0, 0)); + } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr index 761bc370cf49..1703f951a530 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr @@ -39,6 +39,8 @@ impl PublicKernelSetupCircuitPrivateInputs { // validate the inputs unique to having a previous private kernel self.validate_inputs(); + common::update_non_revertible_gas_used(self.public_call, &mut public_inputs); + // Pops the item from the call stack and validates it against the current execution. let call_request = public_inputs.end_non_revertible.public_call_stack.pop(); common::validate_call_against_request(self.public_call, call_request); @@ -47,13 +49,6 @@ impl PublicKernelSetupCircuitPrivateInputs { common::update_public_end_non_revertible_values(self.public_call, &mut public_inputs); - common::accumulate_unencrypted_logs( - self.public_call, - self.previous_kernel.public_inputs.end.unencrypted_logs_hash, - self.previous_kernel.public_inputs.end.unencrypted_log_preimages_length, - &mut public_inputs - ); - public_inputs.finish() } } @@ -68,13 +63,13 @@ mod tests { }; use dep::types::{ abis::{ - call_request::CallRequest, function_selector::FunctionSelector, + call_request::CallRequest, function_selector::FunctionSelector, gas::Gas, kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, max_block_number::MaxBlockNumber, public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, public_call_data::PublicCallData, read_request::ReadRequest }, address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId, - contrakt::storage_read::StorageRead, hash::compute_logs_hash, + contrakt::storage_read::StorageRead, tests::{fixture_builder::FixtureBuilder, public_call_data_builder::PublicCallDataBuilder}, utils::{arrays::{array_eq, array_length}} }; @@ -442,25 +437,24 @@ mod tests { // Logs for the previous call stack. let prev_encrypted_logs_hash = 80; let prev_encrypted_log_preimages_length = 13; - let prev_unencrypted_logs_hash = 956; + let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_revertible.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_revertible.set_unencrypted_logs( + builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.set_unencrypted_logs( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); let public_inputs = builder.execute(); - - assert_eq(public_inputs.end.encrypted_log_preimages_length, prev_encrypted_log_preimages_length); + + assert_eq(public_inputs.end_non_revertible.encrypted_log_preimages_length, prev_encrypted_log_preimages_length); assert_eq( - public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length + public_inputs.end_non_revertible.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length ); - assert_eq(public_inputs.end.encrypted_logs_hash, prev_encrypted_logs_hash); - - let expected_unencrypted_logs_hash = compute_logs_hash(prev_unencrypted_logs_hash, unencrypted_logs_hash); - assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); + assert_eq(public_inputs.end_non_revertible.encrypted_logs_hashes[0].value, prev_encrypted_logs_hash); + assert_eq(public_inputs.end_non_revertible.unencrypted_logs_hashes[0].value, prev_unencrypted_logs_hash); + assert_eq(public_inputs.end_non_revertible.unencrypted_logs_hashes[1].value, unencrypted_logs_hash); } #[test] @@ -496,4 +490,31 @@ mod tests { builder.failed(); } + + #[test] + fn updates_non_revertible_gas_used() { + let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new(); + + // Transaction gas limit is 1k + builder.previous_kernel.gas_settings.da.gas_limit = 1000; + builder.previous_kernel.gas_settings.l1.gas_limit = 1000; + builder.previous_kernel.gas_settings.l2.gas_limit = 1000; + + // Revertible has already used 100 + builder.previous_revertible.gas_used = Gas::new(100, 100, 100); + + // And non-revertible has used another 200 + builder.previous_kernel.gas_used = Gas::new(200, 200, 200); + + // So this call starts with 700 gas left + builder.public_call.public_inputs.call_context.gas_left = Gas::new(700, 700, 700); + + // And uses 300, ending with 400 left + builder.public_call.public_inputs.gas_left = Gas::new(400, 400, 400); + + // So the updated gas used by non-revertible must go up by 300, and revertible must stay the same + let output = builder.execute(); + assert_eq(output.end_non_revertible.gas_used, Gas::new(500, 500, 500)); + assert_eq(output.end.gas_used, Gas::new(100, 100, 100)); + } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr index 23ab10347794..c2804fd67bb1 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr @@ -1,29 +1,28 @@ use crate::common; use dep::reset_kernel_lib::{ - NullifierReadRequestHints, NullifierNonExistentReadRequestHints, reset_non_existent_read_requests, - reset_read_requests + NullifierReadRequestHints, NullifierNonExistentReadRequestHints, PublicDataReadRequestHints, + PublicValidationRequestProcessor, PublicDataHint }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder}, - kernel_data::PublicKernelData, side_effect::SideEffectLinkedToNoteHash + accumulated_data::CombinedAccumulatedData, kernel_circuit_public_inputs::KernelCircuitPublicInputs, + kernel_data::PublicKernelData }, - constants::MAX_NEW_NULLIFIERS_PER_TX, - utils::{arrays::{array_length, array_merge, array_to_bounded_vec, assert_sorted_array}}, - hash::silo_nullifier, traits::is_empty + constants::MAX_PUBLIC_DATA_HINTS, + merkle_tree::{conditionally_assert_check_membership, MembershipWitness}, + partial_state_reference::PartialStateReference, utils::{arrays::array_length} }; struct PublicKernelTailCircuitPrivateInputs { previous_kernel: PublicKernelData, nullifier_read_request_hints: NullifierReadRequestHints, nullifier_non_existent_read_request_hints: NullifierNonExistentReadRequestHints, + public_data_hints: [PublicDataHint; MAX_PUBLIC_DATA_HINTS], + public_data_read_request_hints: PublicDataReadRequestHints, + start_state: PartialStateReference, } impl PublicKernelTailCircuitPrivateInputs { - fn propagate_revert_code(self, public_inputs: &mut PublicKernelCircuitPublicInputsBuilder) { - public_inputs.revert_code = self.previous_kernel.public_inputs.revert_code; - } - fn validate_inputs(self) { let previous_public_inputs = self.previous_kernel.public_inputs; assert(previous_public_inputs.needs_setup() == false, "Previous kernel needs setup"); @@ -37,106 +36,97 @@ impl PublicKernelTailCircuitPrivateInputs { ); } - fn validate_nullifier_read_requests(self, public_inputs: &mut PublicKernelCircuitPublicInputsBuilder) { - let end_non_revertible = self.previous_kernel.public_inputs.end_non_revertible; - let end = self.previous_kernel.public_inputs.end; - - let requests = self.previous_kernel.public_inputs.validation_requests.nullifier_read_requests; - - let pending_nullifiers = array_merge(end_non_revertible.new_nullifiers, end.new_nullifiers); - - let hints = self.nullifier_read_request_hints; - - let nullifier_tree_root = public_inputs.constants.historical_header.state.partial.nullifier_tree.root; - - let unverified_nullifier_read_requests = reset_read_requests( - requests, - pending_nullifiers, - hints.read_request_statuses, - hints.pending_read_hints, - hints.settled_read_hints, - nullifier_tree_root - ); - - assert( - unverified_nullifier_read_requests.len() == 0, "All nullifier read requests must be verified" - ); - } - - fn validate_nullifier_non_existent_read_requests(self, public_inputs: &mut PublicKernelCircuitPublicInputsBuilder) { - let end_non_revertible = self.previous_kernel.public_inputs.end_non_revertible; - let end = self.previous_kernel.public_inputs.end; - - // The values of the read requests here need to be siloed. - // Notice that it's not the case for regular read requests, which can be run between two kernel iterations, and will to be verified against unsiloed pending values. - let mut read_requests = self.previous_kernel.public_inputs.validation_requests.nullifier_non_existent_read_requests; - for i in 0..read_requests.len() { - let read_request = read_requests[i]; - if !is_empty(read_request) { - read_requests[i].value = silo_nullifier(read_request.contract_address, read_request.value); + fn validate_public_data_hints(self) { + let public_data_hints = self.public_data_hints; + let public_data_tree_root = self.start_state.public_data_tree.root; + for i in 0..public_data_hints.len() { + let hint = public_data_hints[i]; + // We only need to check leaf_slot to decide if a (non-)membership check is required. + // It will fail if a PublicDataHint with 0 leaf_slot is used to verify a non-empty public read or write. + if hint.leaf_slot != 0 { + let exists_in_tree = hint.leaf_slot == hint.leaf_preimage.slot; + if exists_in_tree { + assert( + hint.value == hint.leaf_preimage.value, "Hinted public data value does not match the value in leaf preimage" + ); + } else { + assert(hint.value == 0, "Value must be 0 for non-existent public data"); + } + + conditionally_assert_check_membership( + hint.leaf_slot, + exists_in_tree, + hint.leaf_preimage, + MembershipWitness { leaf_index: hint.membership_witness.leaf_index, sibling_path: hint.membership_witness.sibling_path }, + public_data_tree_root + ); } } + } - let nullifier_tree_root = public_inputs.constants.historical_header.state.partial.nullifier_tree.root; - - let hints = self.nullifier_non_existent_read_request_hints; - - let pending_nullifiers = array_merge(end_non_revertible.new_nullifiers, end.new_nullifiers); - assert_sorted_array( - pending_nullifiers, - hints.sorted_pending_values, - hints.sorted_pending_value_index_hints, - |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.value.lt(b.value) - ); - let sorted_pending_nullifiers = array_to_bounded_vec(hints.sorted_pending_values); - - reset_non_existent_read_requests( - read_requests, - hints.non_membership_hints, - nullifier_tree_root, - sorted_pending_nullifiers, - hints.next_pending_value_indices - ); + fn propagate_accumulated_data(self) -> CombinedAccumulatedData { + let previous_public_inputs = self.previous_kernel.public_inputs; + // TODO: Sort the combined data. + CombinedAccumulatedData::combine( + previous_public_inputs.end_non_revertible, + previous_public_inputs.end + ) } pub fn public_kernel_tail(self) -> KernelCircuitPublicInputs { - let mut public_inputs = PublicKernelCircuitPublicInputsBuilder::empty(); - self.validate_inputs(); - self.propagate_revert_code(&mut public_inputs); - - common::initialize_emitted_end_values(self.previous_kernel, &mut public_inputs); + self.validate_public_data_hints(); - self.validate_nullifier_read_requests(&mut public_inputs); + let previous_public_inputs = self.previous_kernel.public_inputs; + let request_processor = PublicValidationRequestProcessor::new( + previous_public_inputs, + self.nullifier_read_request_hints, + self.nullifier_non_existent_read_request_hints, + self.start_state.nullifier_tree.root, + self.public_data_read_request_hints, + self.public_data_hints + ); + request_processor.validate(); - self.validate_nullifier_non_existent_read_requests(&mut public_inputs); + let end = self.propagate_accumulated_data(); - public_inputs.finish_tail() + KernelCircuitPublicInputs { + aggregation_object: previous_public_inputs.aggregation_object, + rollup_validation_requests: previous_public_inputs.validation_requests.for_rollup, + end, + constants: previous_public_inputs.constants, + start_state: self.start_state, + revert_code: previous_public_inputs.revert_code + } } } mod tests { - use crate::{public_kernel_tail::PublicKernelTailCircuitPrivateInputs}; + use crate::public_kernel_tail::PublicKernelTailCircuitPrivateInputs; use dep::reset_kernel_lib::{ tests::{ nullifier_non_existent_read_request_hints_builder::NullifierNonExistentReadRequestHintsBuilder, - nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder + nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder, + public_data_read_request_hints_builder::PublicDataReadRequestHintsBuilder }, - read_request_reset::{PendingReadHint, ReadRequestState, ReadRequestStatus} + PublicDataHint, reset::read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus} }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder}, - kernel_data::PublicKernelData, nullifier_leaf_preimage::NullifierLeafPreimage + kernel_circuit_public_inputs::KernelCircuitPublicInputs, kernel_data::PublicKernelData, + nullifier_leaf_preimage::NullifierLeafPreimage, membership_witness::PublicDataMembershipWitness }, constants::{ - MAX_NEW_NULLIFIERS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT, - NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT + MAX_NEW_NULLIFIERS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_PUBLIC_DATA_HINTS, + MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT, + NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_HEIGHT, + PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_TREE_HEIGHT }, - hash::silo_nullifier, + hash::{silo_nullifier, accumulate_sha256}, + public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage, tests::{fixture_builder::FixtureBuilder, merkle_tree_utils::NonEmptyMerkleTree}, - utils::arrays::array_merge + partial_state_reference::PartialStateReference, utils::arrays::array_merge }; fn build_nullifier_tree() -> NonEmptyMerkleTree { @@ -151,11 +141,33 @@ mod tests { ) } + fn get_settled_public_data_leaves() -> [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] { + let mut settled_public_data_leaves = [PublicDataTreeLeafPreimage::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; + settled_public_data_leaves[0] = PublicDataTreeLeafPreimage { slot: 22, value: 200, next_slot: 33, next_index: 1 }; + settled_public_data_leaves[1] = PublicDataTreeLeafPreimage { slot: 33, value: 300, next_slot: 0, next_index: 0 }; + settled_public_data_leaves[2] = PublicDataTreeLeafPreimage { slot: 11, value: 100, next_slot: 22, next_index: 0 }; + settled_public_data_leaves + } + + fn build_public_data_tree() -> NonEmptyMerkleTree { + let settled_public_data_leaves = get_settled_public_data_leaves(); + NonEmptyMerkleTree::new( + settled_public_data_leaves.map(|preimage: PublicDataTreeLeafPreimage| preimage.hash()), + [0; PUBLIC_DATA_TREE_HEIGHT], + [0; PUBLIC_DATA_TREE_HEIGHT - PUBLIC_DATA_SUBTREE_HEIGHT], + [0; PUBLIC_DATA_SUBTREE_HEIGHT] + ) + } + struct PublicKernelTailCircuitPrivateInputsBuilder { previous_kernel: FixtureBuilder, previous_revertible: FixtureBuilder, nullifier_read_request_hints_builder: NullifierReadRequestHintsBuilder, nullifier_non_existent_read_request_hints_builder: NullifierNonExistentReadRequestHintsBuilder, + public_data_read_request_hints_builder: PublicDataReadRequestHintsBuilder, + public_data_hints: BoundedVec, + public_data_tree: NonEmptyMerkleTree, + start_state: PartialStateReference, } impl PublicKernelTailCircuitPrivateInputsBuilder { @@ -168,7 +180,11 @@ mod tests { previous_kernel, previous_revertible, nullifier_read_request_hints_builder: NullifierReadRequestHintsBuilder::new(MAX_NULLIFIER_READ_REQUESTS_PER_TX), - nullifier_non_existent_read_request_hints_builder + nullifier_non_existent_read_request_hints_builder, + public_data_read_request_hints_builder: PublicDataReadRequestHintsBuilder::new(MAX_PUBLIC_DATA_READS_PER_TX), + public_data_hints: BoundedVec::new(), + public_data_tree: NonEmptyMerkleTree::empty(), + start_state: PartialStateReference::empty() }; builder.set_nullifiers_for_non_existent_read_request_hints(); builder @@ -176,8 +192,17 @@ mod tests { pub fn with_nullifier_tree(&mut self) -> Self { let nullifier_tree = build_nullifier_tree(); - self.previous_kernel.historical_header.state.partial.nullifier_tree.root = nullifier_tree.get_root(); self.nullifier_non_existent_read_request_hints_builder.set_nullifier_tree(nullifier_tree); + let tree_root = nullifier_tree.get_root(); + self.start_state.nullifier_tree.root = tree_root; + self.previous_kernel.historical_header.state.partial.nullifier_tree.root = tree_root; + *self + } + + pub fn with_public_data_tree(&mut self) -> Self { + let public_data_tree = build_public_data_tree(); + self.public_data_tree = public_data_tree; + self.start_state.public_data_tree.root = public_data_tree.get_root(); *self } @@ -236,6 +261,37 @@ mod tests { self.nullifier_non_existent_read_request_hints_builder.add_value_read(siloed_nullifier); } + pub fn add_public_data_hint_for_settled_public_data(&mut self, leaf_index: u64) { + let leaf_preimage = get_settled_public_data_leaves()[leaf_index]; + let membership_witness = PublicDataMembershipWitness { leaf_index: leaf_index as Field, sibling_path: self.public_data_tree.get_sibling_path(leaf_index) }; + let hint = PublicDataHint { + leaf_slot: leaf_preimage.slot, + value: leaf_preimage.value, + override_counter: 0, + membership_witness, + leaf_preimage + }; + self.public_data_hints.push(hint); + } + + pub fn add_public_data_hint_for_non_existent_public_data(&mut self, leaf_slot: Field, low_leaf_index: u64) { + let leaf_preimage = get_settled_public_data_leaves()[low_leaf_index]; + let membership_witness = PublicDataMembershipWitness { + leaf_index: low_leaf_index as Field, + sibling_path: self.public_data_tree.get_sibling_path(low_leaf_index) + }; + let hint = PublicDataHint { leaf_slot, value: 0, override_counter: 0, membership_witness, leaf_preimage }; + self.public_data_hints.push(hint); + } + + pub fn add_pending_public_data_read_request(&mut self, public_date_update_request_index: u64) { + let read_request_index = self.previous_kernel.add_read_request_for_pending_public_data(public_date_update_request_index); + let hint_index = self.public_data_read_request_hints_builder.pending_read_hints.len(); + let hint = PendingReadHint { read_request_index, pending_value_index: public_date_update_request_index }; + self.public_data_read_request_hints_builder.pending_read_hints.push(hint); + self.public_data_read_request_hints_builder.read_request_statuses[read_request_index] = ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; + } + fn sync_counters(&mut self) { let counter_non_revertible = self.previous_kernel.counter; let counter_revertible = self.previous_revertible.counter; @@ -253,7 +309,10 @@ mod tests { let kernel = PublicKernelTailCircuitPrivateInputs { previous_kernel, nullifier_read_request_hints: self.nullifier_read_request_hints_builder.to_hints(), - nullifier_non_existent_read_request_hints: self.nullifier_non_existent_read_request_hints_builder.to_hints() + nullifier_non_existent_read_request_hints: self.nullifier_non_existent_read_request_hints_builder.to_hints(), + public_data_hints: self.public_data_hints.storage, + public_data_read_request_hints: self.public_data_read_request_hints_builder.to_hints(), + start_state: self.start_state }; kernel.public_kernel_tail() @@ -275,6 +334,38 @@ mod tests { // TODO: Check the values in public inputs. } + #[test] + fn logs_are_handled_as_expected() { + let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); + // Logs for the previous call stack. + let prev_encrypted_logs_hash = 80; + let prev_encrypted_log_preimages_length = 13; + let prev_unencrypted_logs_hash = 956; + let prev_unencrypted_log_preimages_length = 24; + builder.previous_revertible.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_revertible.set_unencrypted_logs( + prev_unencrypted_logs_hash, + prev_unencrypted_log_preimages_length + ); + // Logs for the current call stack. + let unencrypted_logs_hash = 26; + let unencrypted_log_preimages_length = 50; + builder.previous_revertible.set_unencrypted_logs(unencrypted_logs_hash, unencrypted_log_preimages_length); + + let public_inputs = builder.execute(); + + assert_eq(public_inputs.end.encrypted_log_preimages_length, prev_encrypted_log_preimages_length); + assert_eq( + public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length + ); + + let expected_encrypted_logs_hash = accumulate_sha256([0, prev_encrypted_logs_hash]); + assert_eq(public_inputs.end.encrypted_logs_hash, expected_encrypted_logs_hash); + let mut expected_unencrypted_logs_hash = accumulate_sha256([0, prev_unencrypted_logs_hash]); + expected_unencrypted_logs_hash = accumulate_sha256([expected_unencrypted_logs_hash, unencrypted_logs_hash]); + assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); + } + #[test] unconstrained fn one_pending_nullifier_read_request() { let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); @@ -356,6 +447,95 @@ mod tests { builder.read_non_existent_nullifier(1); + builder.failed(); + } + + #[test] + unconstrained fn validate_public_data_hints() { + let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new().with_public_data_tree(); + + builder.add_public_data_hint_for_settled_public_data(1); + builder.add_public_data_hint_for_settled_public_data(0); + builder.add_public_data_hint_for_settled_public_data(2); + builder.succeeded(); } + + #[test(should_fail_with="Hinted public data value does not match the value in leaf preimage")] + unconstrained fn validate_public_data_hints_failed_mismatch_value() { + let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new().with_public_data_tree(); + + builder.add_public_data_hint_for_settled_public_data(1); + + let mut hint = builder.public_data_hints.pop(); + hint.value += 1; + builder.public_data_hints.push(hint); + + builder.failed(); + } + + #[test] + unconstrained fn validate_public_data_hints_uninitialized_value() { + let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new().with_public_data_tree(); + + builder.add_public_data_hint_for_non_existent_public_data(25, 0); + + builder.succeeded(); + } + + #[test(should_fail_with="Value must be 0 for non-existent public data")] + unconstrained fn validate_public_data_hints_failed_non_zero_uninitialized_value() { + let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new().with_public_data_tree(); + + builder.add_public_data_hint_for_non_existent_public_data(25, 0); + + let mut hint = builder.public_data_hints.pop(); + hint.value = 1; + builder.public_data_hints.push(hint); + + builder.failed(); + } + + #[test] + unconstrained fn pending_public_data_read_requests() { + let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); + + builder.previous_kernel.append_public_data_update_requests(3); + + builder.add_pending_public_data_read_request(1); + builder.add_pending_public_data_read_request(0); + builder.add_pending_public_data_read_request(2); + + builder.succeeded(); + } + + #[test(should_fail_with="Hinted slot of data write does not match read request")] + unconstrained fn pending_public_data_read_requests_failed_wrong_write_index() { + let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); + + builder.previous_kernel.append_public_data_update_requests(2); + + builder.add_pending_public_data_read_request(1); + + let mut hint = builder.public_data_read_request_hints_builder.pending_read_hints.pop(); + hint.pending_value_index += 1; + builder.public_data_read_request_hints_builder.pending_read_hints.push(hint); + + builder.failed(); + } + + #[test(should_fail_with="Hinted value of data write does not match read request")] + unconstrained fn pending_public_data_read_requests_failed_wrong_write_value() { + let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); + + builder.previous_kernel.append_public_data_update_requests(1); + + builder.add_pending_public_data_read_request(0); + + let mut public_data_write = builder.previous_kernel.public_data_update_requests.pop(); + public_data_write.new_value += 1; + builder.previous_kernel.public_data_update_requests.push(public_data_write); + + builder.failed(); + } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr index 70600fda54ca..67b89c28167d 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr @@ -46,15 +46,6 @@ impl PublicKernelTeardownCircuitPrivateInputs { common::update_public_end_non_revertible_values(self.public_call, &mut public_inputs); - if public_inputs.revert_code == 0 { - common::accumulate_unencrypted_logs( - self.public_call, - self.previous_kernel.public_inputs.end.unencrypted_logs_hash, - self.previous_kernel.public_inputs.end.unencrypted_log_preimages_length, - &mut public_inputs - ); - } - public_inputs.finish() } } @@ -74,7 +65,7 @@ mod tests { public_data_update_request::PublicDataUpdateRequest }, address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId, - contrakt::storage_read::StorageRead, hash::compute_logs_hash, + contrakt::storage_read::StorageRead, tests::{fixture_builder::FixtureBuilder, public_call_data_builder::PublicCallDataBuilder}, utils::{arrays::{array_eq, array_length}} }; @@ -348,23 +339,21 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_revertible.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_revertible.set_unencrypted_logs( + builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.set_unencrypted_logs( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); let public_inputs = builder.execute(); - assert_eq(public_inputs.end.encrypted_log_preimages_length, prev_encrypted_log_preimages_length); + assert_eq(public_inputs.end_non_revertible.encrypted_log_preimages_length, prev_encrypted_log_preimages_length); assert_eq( - public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length + public_inputs.end_non_revertible.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length ); - - assert_eq(public_inputs.end.encrypted_logs_hash, prev_encrypted_logs_hash); - - let expected_unencrypted_logs_hash = compute_logs_hash(prev_unencrypted_logs_hash, unencrypted_logs_hash); - assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); + assert_eq(public_inputs.end_non_revertible.encrypted_logs_hashes[0].value, prev_encrypted_logs_hash); + assert_eq(public_inputs.end_non_revertible.unencrypted_logs_hashes[0].value, prev_unencrypted_logs_hash); + assert_eq(public_inputs.end_non_revertible.unencrypted_logs_hashes[1].value, unencrypted_logs_hash); } #[test(should_fail_with="Public call cannot be reverted")] diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr index a156e40f1a66..8a7ffb5e38bb 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr @@ -1,12 +1,15 @@ -use non_existent_read_request_reset::reset_non_existent_read_requests; use nullifier_non_existent_read_request_reset::NullifierNonExistentReadRequestHints; use nullifier_read_request_reset::NullifierReadRequestHints; use private_validation_request_processor::PrivateValidationRequestProcessor; -use read_request_reset::reset_read_requests; +use public_data_read_request_reset::PublicDataReadRequestHints; +use public_validation_request_processor::PublicValidationRequestProcessor; +use types::public_data_hint::PublicDataHint; -mod non_existent_read_request_reset; mod nullifier_non_existent_read_request_reset; mod nullifier_read_request_reset; mod private_validation_request_processor; -mod read_request_reset; +mod public_data_read_request_reset; +mod public_validation_request_processor; +mod reset; mod tests; +mod types; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_non_existent_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_non_existent_read_request_reset.nr index cc76145b18e6..5f9f7548782d 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_non_existent_read_request_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_non_existent_read_request_reset.nr @@ -1,7 +1,7 @@ -use crate::non_existent_read_request_reset::{NonMembershipHint}; +use crate::reset::non_existent_read_request::NonMembershipHint; use dep::types::{ abis::{nullifier_leaf_preimage::NullifierLeafPreimage, side_effect::SideEffectLinkedToNoteHash}, - merkle_tree::{MembershipWitness}, + merkle_tree::MembershipWitness, constants::{MAX_NEW_NULLIFIERS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT} }; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_read_request_reset.nr index cb2e0abc875e..de2da03dc8cd 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_read_request_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_read_request_reset.nr @@ -1,5 +1,5 @@ // This will be moved to a separate Read Request Reset Circuit. -use crate::read_request_reset::{PendingReadHint, ReadRequestStatus, ReadValueHint, SettledReadHint}; +use crate::reset::read_request::{PendingReadHint, ReadRequestStatus, ReadValueHint, SettledReadHint}; use dep::types::{ abis::{nullifier_leaf_preimage::NullifierLeafPreimage}, constants::{MAX_NULLIFIER_READ_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT}, @@ -44,7 +44,7 @@ struct NullifierReadRequestHints { mod tests { use crate::nullifier_read_request_reset::NullifierSettledReadHint; - use crate::read_request_reset::{PendingReadHint, ReadRequestState, ReadRequestStatus, reset_read_requests}; + use crate::reset::read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus, reset_read_requests}; use dep::types::{ address::AztecAddress, abis::{ diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr index 9f60134dd45d..469a4d6d9bf7 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr @@ -1,4 +1,4 @@ -use crate::{nullifier_read_request_reset::NullifierReadRequestHints, read_request_reset::reset_read_requests}; +use crate::{nullifier_read_request_reset::NullifierReadRequestHints, reset::read_request::reset_read_requests}; use dep::types::{ abis::{side_effect::{SideEffect, SideEffectLinkedToNoteHash}, validation_requests::ValidationRequests}, constants::{ diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_data_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_data_read_request_reset.nr new file mode 100644 index 000000000000..7c6b66340742 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_data_read_request_reset.nr @@ -0,0 +1,9 @@ +use crate::reset::{mutable_data_read_request::LeafDataReadHint, read_request::{PendingReadHint, ReadRequestStatus}}; +use dep::types::constants::MAX_PUBLIC_DATA_READS_PER_TX; + +// The MAX_PUBLIC_DATA_READS_PER_TX for pending_read_hints and leaf_data_read_hints can change if we create various circuits that deal with different number of reads. +struct PublicDataReadRequestHints { + read_request_statuses: [ReadRequestStatus; MAX_PUBLIC_DATA_READS_PER_TX], + pending_read_hints: [PendingReadHint; MAX_PUBLIC_DATA_READS_PER_TX], + leaf_data_read_hints: [LeafDataReadHint; MAX_PUBLIC_DATA_READS_PER_TX], +} diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_validation_request_processor.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_validation_request_processor.nr new file mode 100644 index 000000000000..4a74f99fd5b5 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_validation_request_processor.nr @@ -0,0 +1,127 @@ +use crate::{ + reset::{ + non_existent_read_request::reset_non_existent_read_requests, + mutable_data_read_request::reset_mutable_data_read_requests, read_request::reset_read_requests +}, + nullifier_read_request_reset::NullifierReadRequestHints, + nullifier_non_existent_read_request_reset::NullifierNonExistentReadRequestHints, + public_data_read_request_reset::PublicDataReadRequestHints, types::public_data_hint::PublicDataHint +}; +use dep::types::{ + abis::{ + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + public_data_update_request::PublicDataUpdateRequest, side_effect::SideEffectLinkedToNoteHash, + validation_requests::ValidationRequests +}, + constants::{MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX}, + hash::silo_nullifier, traits::is_empty, + utils::arrays::{array_merge, array_to_bounded_vec, assert_sorted_array} +}; + +struct PublicValidationRequestProcessor { + validation_requests: ValidationRequests, + pending_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], + pending_public_data_writes: [PublicDataUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], + nullifier_read_request_hints: NullifierReadRequestHints, + nullifier_non_existent_read_request_hints: NullifierNonExistentReadRequestHints, + nullifier_tree_root: Field, + public_data_read_request_hints: PublicDataReadRequestHints, + public_data_hints: [PublicDataHint; N], +} + +impl PublicValidationRequestProcessor { + pub fn new( + public_inputs: PublicKernelCircuitPublicInputs, + nullifier_read_request_hints: NullifierReadRequestHints, + nullifier_non_existent_read_request_hints: NullifierNonExistentReadRequestHints, + nullifier_tree_root: Field, + public_data_read_request_hints: PublicDataReadRequestHints, + public_data_hints: [PublicDataHint; N] + ) -> Self { + let end_non_revertible = public_inputs.end_non_revertible; + let end = public_inputs.end; + + let pending_nullifiers = array_merge(end_non_revertible.new_nullifiers, end.new_nullifiers); + + let pending_public_data_writes = array_merge( + end_non_revertible.public_data_update_requests, + end.public_data_update_requests + ); + + PublicValidationRequestProcessor { + validation_requests: public_inputs.validation_requests, + pending_nullifiers, + pending_public_data_writes, + nullifier_read_request_hints, + nullifier_non_existent_read_request_hints, + nullifier_tree_root, + public_data_read_request_hints, + public_data_hints + } + } + + pub fn validate(self) { + self.validate_nullifier_read_requests(); + self.validate_nullifier_non_existent_read_requests(); + self.validate_public_data_read_requests(); + } + + fn validate_nullifier_read_requests(self) { + let requests = self.validation_requests.nullifier_read_requests; + let hints = self.nullifier_read_request_hints; + let unverified_nullifier_read_requests = reset_read_requests( + requests, + self.pending_nullifiers, + hints.read_request_statuses, + hints.pending_read_hints, + hints.settled_read_hints, + self.nullifier_tree_root + ); + assert( + unverified_nullifier_read_requests.len() == 0, "All nullifier read requests must be verified" + ); + } + + fn validate_nullifier_non_existent_read_requests(self) { + // The values of the read requests here need to be siloed. + // Notice that it's not the case for regular read requests, which can be run between two kernel iterations, and will to be verified against unsiloed pending values. + let mut read_requests = self.validation_requests.nullifier_non_existent_read_requests; + for i in 0..read_requests.len() { + let read_request = read_requests[i]; + if !is_empty(read_request) { + read_requests[i].value = silo_nullifier(read_request.contract_address, read_request.value); + } + } + + let hints = self.nullifier_non_existent_read_request_hints; + + assert_sorted_array( + self.pending_nullifiers, + hints.sorted_pending_values, + hints.sorted_pending_value_index_hints, + |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.value.lt(b.value) + ); + let sorted_pending_nullifiers = array_to_bounded_vec(hints.sorted_pending_values); + + reset_non_existent_read_requests( + read_requests, + hints.non_membership_hints, + self.nullifier_tree_root, + sorted_pending_nullifiers, + hints.next_pending_value_indices + ); + } + + fn validate_public_data_read_requests(self) { + let hints = self.public_data_read_request_hints; + + reset_mutable_data_read_requests( + self.validation_requests.public_data_reads, + hints.read_request_statuses, + self.pending_public_data_writes, + self.public_data_hints, + hints.pending_read_hints, + hints.leaf_data_read_hints + ); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset.nr new file mode 100644 index 000000000000..8b98420b3cd1 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset.nr @@ -0,0 +1,3 @@ +mod mutable_data_read_request; +mod non_existent_read_request; +mod read_request; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/mutable_data_read_request.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/mutable_data_read_request.nr new file mode 100644 index 000000000000..a86ab40f20d6 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/mutable_data_read_request.nr @@ -0,0 +1,320 @@ +use crate::reset::read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus}; +use dep::types::{ + abis::{public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest}, + traits::{Empty, is_empty} +}; + +trait LeafDataHint { + fn leaf_slot(self) -> Field; + fn value(self) -> Field; + fn override_counter(self) -> u32; +} + +struct LeafDataReadHint { + read_request_index: u64, + data_hint_index: u64, +} + +impl LeafDataReadHint { + pub fn nada(read_request_len: u64) -> Self { + LeafDataReadHint { read_request_index: read_request_len, data_hint_index: 0 } + } +} + +fn validate_pending_read_requests( + read_requests: [PublicDataRead; READ_REQUEST_LEN], + data_writes: [PublicDataUpdateRequest; PENDING_VALUE_LEN], + hints: [PendingReadHint; NUM_PENDING_READS] +) { + for i in 0..NUM_PENDING_READS { + let read_request_index = hints[i].read_request_index; + if read_request_index != READ_REQUEST_LEN { + let read_request = read_requests[read_request_index]; + let pending_value = data_writes[hints[i].pending_value_index]; + assert( + read_request.leaf_slot.eq(pending_value.leaf_slot), "Hinted slot of data write does not match read request" + ); + assert( + read_request.value.eq(pending_value.new_value), "Hinted value of data write does not match read request" + ); + // TODO: Add counters and verify the following: + // assert( + // read_request.counter > pending_value.counter, "Read request counter must be greater than the counter of the data write" + // ); + // assert((read_request.counter < pending_value.next_counter) | (pending_value.next_counter == 0), "Read request counter must be less than the counter of the next data write"); + } + } +} + +fn validate_leaf_data_read_requests( + read_requests: [PublicDataRead; READ_REQUEST_LEN], + leaf_data_hints: [H; NUM_LEAF_DATA_HINTS], + hints: [LeafDataReadHint; NUM_LEAF_DATA_READS] +) where H: LeafDataHint { + for i in 0..NUM_LEAF_DATA_READS { + let read_request_index = hints[i].read_request_index; + if read_request_index != READ_REQUEST_LEN { + let read_request = read_requests[read_request_index]; + let data_hint = leaf_data_hints[hints[i].data_hint_index]; + assert( + read_request.leaf_slot == data_hint.leaf_slot(), "Hinted slot does not match read request" + ); + assert(read_request.value == data_hint.value(), "Hinted value does not match read request"); + // TODO: Add counters and verify the following: + // assert((read_request.counter < data_hint.override_counter) | (data_hint.override_counter == 0), "Hinted leaf is overridden before the read request"); + } + } +} + +fn ensure_all_read_requests_are_verified( + read_requests: [PublicDataRead; READ_REQUEST_LEN], + read_request_statuses: [ReadRequestStatus; READ_REQUEST_LEN], + pending_read_hints: [PendingReadHint; NUM_PENDING_READS], + leaf_data_read_hints: [LeafDataReadHint; NUM_LEAF_DATA_READS] +) { + for i in 0..READ_REQUEST_LEN { + let read_request = read_requests[i]; + if !is_empty(read_request) { + let status = read_request_statuses[i]; + if status.state == ReadRequestState.PENDING { + assert( + pending_read_hints[status.hint_index].read_request_index == i, "Hinted pending read request does not match status" + ); + } else if status.state == ReadRequestState.SETTLED { + assert( + leaf_data_read_hints[status.hint_index].read_request_index == i, "Hinted settled read request does not match status" + ); + } else { + assert(false, "Read request status must be PENDING or SETTLED"); + } + } + } +} + +pub fn reset_mutable_data_read_requests( + read_requests: [PublicDataRead; READ_REQUEST_LEN], + read_request_statuses: [ReadRequestStatus; READ_REQUEST_LEN], + data_writes: [PublicDataUpdateRequest; PENDING_VALUE_LEN], + leaf_data_hints: [H; NUM_LEAF_DATA_HINTS], + pending_read_hints: [PendingReadHint; NUM_PENDING_READS], + leaf_data_read_hints: [LeafDataReadHint; NUM_LEAF_DATA_READS] +) where H: LeafDataHint { + validate_pending_read_requests(read_requests, data_writes, pending_read_hints); + + validate_leaf_data_read_requests(read_requests, leaf_data_hints, leaf_data_read_hints); + + ensure_all_read_requests_are_verified( + read_requests, + read_request_statuses, + pending_read_hints, + leaf_data_read_hints + ); +} + +mod tests { + use crate::reset::{ + mutable_data_read_request::{ + ensure_all_read_requests_are_verified, reset_mutable_data_read_requests, LeafDataHint, + LeafDataReadHint, validate_pending_read_requests, validate_leaf_data_read_requests + }, + read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus} + }; + use dep::types::{abis::{public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest}}; + + struct TestLeafDataHint { + leaf_slot: Field, + value: Field, + } + + impl LeafDataHint for TestLeafDataHint { + fn leaf_slot(self) -> Field { + self.leaf_slot + } + + fn value(self) -> Field { + self.value + } + + fn override_counter(_self: Self) -> u32 { + 0 + } + } + + global data_writes = [ + PublicDataUpdateRequest { leaf_slot: 22, new_value: 200 }, + PublicDataUpdateRequest { leaf_slot: 11, new_value: 100 }, + PublicDataUpdateRequest { leaf_slot: 33, new_value: 300 }, + PublicDataUpdateRequest { leaf_slot: 44, new_value: 400 } + ]; + + global leaf_data_hints = [ + TestLeafDataHint { leaf_slot: 7, value: 70 }, + TestLeafDataHint { leaf_slot: 6, value: 60 }, + TestLeafDataHint { leaf_slot: 5, value: 50 }, + ]; + + fn create_pending_read_requests(data_write_indices: [u64; N]) -> ([PublicDataRead; N], [PendingReadHint; N]) { + let read_requests = data_write_indices.map( + |data_write_index: u64| PublicDataRead { leaf_slot: data_writes[data_write_index].leaf_slot, value: data_writes[data_write_index].new_value } + ); + let mut hints = BoundedVec::new(); + for i in 0..N { + hints.push(PendingReadHint { read_request_index: i, pending_value_index: data_write_indices[i] }); + } + (read_requests, hints.storage) + } + + fn create_leaf_data_read_requests(data_hint_indices: [u64; N]) -> ([PublicDataRead; N], [LeafDataReadHint; N]) { + let read_requests = data_hint_indices.map( + |data_hint_index: u64| PublicDataRead { leaf_slot: leaf_data_hints[data_hint_index].leaf_slot, value: leaf_data_hints[data_hint_index].value } + ); + let mut hints = BoundedVec::new(); + for i in 0..N { + hints.push(LeafDataReadHint { read_request_index: i, data_hint_index: data_hint_indices[i] }); + } + (read_requests, hints.storage) + } + + #[test] + fn reset_pending_reads_succeeds() { + let (read_requests, hints) = create_pending_read_requests([2, 0, 1, 3]); + validate_pending_read_requests(read_requests, data_writes, hints); + } + + #[test] + fn reset_pending_reads_repeated_values() { + let (read_requests, hints) = create_pending_read_requests([1, 0, 0, 1]); + validate_pending_read_requests(read_requests, data_writes, hints); + } + + #[test] + fn reset_pending_reads_skips_nada() { + let read_requests = [PublicDataRead { leaf_slot: 88, value: 9999 }]; + let hints = [PendingReadHint::nada(1)]; + validate_pending_read_requests(read_requests, data_writes, hints); + } + + #[test(should_fail_with="Hinted slot of data write does not match read request")] + fn reset_pending_reads_wrong_slot_fails() { + let mut (read_requests, hints) = create_pending_read_requests([1]); + hints[0].pending_value_index = 0; + validate_pending_read_requests(read_requests, data_writes, hints); + } + + #[test(should_fail_with="Hinted value of data write does not match read request")] + fn reset_pending_reads_wrong_value_fails() { + let mut (read_requests, hints) = create_pending_read_requests([1]); + read_requests[0].value += 1; + validate_pending_read_requests(read_requests, data_writes, hints); + } + + #[test] + fn reset_leaf_data_reads_succeeds() { + let (read_requests, hints) = create_leaf_data_read_requests([2, 1, 0]); + validate_leaf_data_read_requests(read_requests, leaf_data_hints, hints); + } + + #[test] + fn reset_leaf_data_reads_repeated_values() { + let (read_requests, hints) = create_leaf_data_read_requests([1, 0, 1, 0]); + validate_leaf_data_read_requests(read_requests, leaf_data_hints, hints); + } + + #[test] + fn reset_leaf_data_reads_skips_nada() { + let read_requests = [PublicDataRead { leaf_slot: 88, value: 9999 }]; + let hints = [LeafDataReadHint::nada(1)]; + validate_leaf_data_read_requests(read_requests, leaf_data_hints, hints); + } + + #[test(should_fail_with=""Hinted slot does not match read request")] + fn reset_leaf_reads_wrong_slot_fails() { + let mut (read_requests, hints) = create_leaf_data_read_requests([1]); + hints[0].data_hint_index = 0; + validate_leaf_data_read_requests(read_requests, leaf_data_hints, hints); + } + + #[test(should_fail_with=""Hinted value does not match read request")] + fn reset_leaf_reads_wrong_value_fails() { + let mut (read_requests, hints) = create_leaf_data_read_requests([1]); + read_requests[0].value += 1; + validate_leaf_data_read_requests(read_requests, leaf_data_hints, hints); + } + + #[test] + fn ensure_all_read_requests_are_verified_succeeds() { + let mut (pending_read_requests, pending_read_hints) = create_pending_read_requests([1]); + let mut (leaf_read_requests, leaf_data_read_hints) = create_leaf_data_read_requests([0, 1]); + let read_requests = [leaf_read_requests[0], pending_read_requests[0], leaf_read_requests[1]]; + pending_read_hints[0].read_request_index = 1; + leaf_data_read_hints[1].read_request_index = 2; + + let statuses = [ + ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 0 }, + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 0 }, + ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 1 } + ]; + + ensure_all_read_requests_are_verified( + read_requests, + statuses, + pending_read_hints, + leaf_data_read_hints + ); + } + + #[test(should_fail_with="Hinted pending read request does not match status")] + fn ensure_all_read_requests_are_verified_wrong_pending_hint_index_fails() { + let (read_requests, hints) = create_pending_read_requests([0, 1]); + let statuses = [ + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 0 }, + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 0 } + ]; + ensure_all_read_requests_are_verified(read_requests, statuses, hints, []); + } + + #[test(should_fail_with="Hinted settled read request does not match status")] + fn ensure_all_read_requests_are_verified_wrong_leaf_hint_index_fails() { + let (read_requests, hints) = create_leaf_data_read_requests([0, 1]); + let statuses = [ + ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 0 }, + ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 0 } + ]; + ensure_all_read_requests_are_verified(read_requests, statuses, [], hints); + } + + #[test(should_fail_with="Read request status must be PENDING or SETTLED")] + fn ensure_all_read_requests_are_verified_wrong_status_fails() { + let (read_requests, hints) = create_leaf_data_read_requests([0]); + let statuses = [ReadRequestStatus { state: ReadRequestState.NADA, hint_index: 0 }]; + ensure_all_read_requests_are_verified(read_requests, statuses, [], hints); + } + + #[test] + fn reset_mutable_data_read_requests_succeeds() { + let mut (pending_read_requests, pending_read_hints) = create_pending_read_requests([3, 1]); + let mut (leaf_read_requests, leaf_data_read_hints) = create_leaf_data_read_requests([0, 1]); + let read_requests = [ + leaf_read_requests[0], pending_read_requests[0], pending_read_requests[1], leaf_read_requests[1] + ]; + pending_read_hints[0].read_request_index = 1; + pending_read_hints[1].read_request_index = 2; + leaf_data_read_hints[1].read_request_index = 3; + + let statuses = [ + ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 0 }, + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 0 }, + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 1 }, + ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 1 } + ]; + + reset_mutable_data_read_requests( + read_requests, + statuses, + data_writes, + leaf_data_hints, + pending_read_hints, + leaf_data_read_hints + ); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/non_existent_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr similarity index 94% rename from noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/non_existent_read_request_reset.nr rename to noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr index 4beeee665ae1..afb50e68ce53 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/non_existent_read_request_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr @@ -86,7 +86,7 @@ pub fn reset_non_existent_read_requests, + leaf_data_read_hints: BoundedVec, +} + +impl PublicDataReadRequestHintsBuilder { + pub fn new(read_request_len: u64) -> Self { + PublicDataReadRequestHintsBuilder { + read_request_statuses: [ReadRequestStatus::empty(); MAX_PUBLIC_DATA_READS_PER_TX], + pending_read_hints: BoundedVec { storage: [PendingReadHint::nada(read_request_len); MAX_PUBLIC_DATA_READS_PER_TX], len: 0 }, + leaf_data_read_hints: BoundedVec { storage: [LeafDataReadHint::nada(read_request_len); MAX_PUBLIC_DATA_READS_PER_TX], len: 0 } + } + } + + pub fn to_hints(self) -> PublicDataReadRequestHints { + PublicDataReadRequestHints { + read_request_statuses: self.read_request_statuses, + pending_read_hints: self.pending_read_hints.storage, + leaf_data_read_hints: self.leaf_data_read_hints.storage + } + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types.nr new file mode 100644 index 000000000000..aa16f1fe6782 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types.nr @@ -0,0 +1 @@ +mod public_data_hint; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types/public_data_hint.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types/public_data_hint.nr new file mode 100644 index 000000000000..28a3eb74cb0c --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/types/public_data_hint.nr @@ -0,0 +1,27 @@ +use crate::reset::{mutable_data_read_request::LeafDataHint}; +use dep::types::{ + abis::membership_witness::PublicDataMembershipWitness, + public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage +}; + +struct PublicDataHint { + leaf_slot: Field, + value: Field, + override_counter: u32, + membership_witness: PublicDataMembershipWitness, // Should be MembershipWitness when we can handle generics when converting to ts types. + leaf_preimage: PublicDataTreeLeafPreimage, +} + +impl LeafDataHint for PublicDataHint { + fn leaf_slot(self) -> Field { + self.leaf_slot + } + + fn value(self) -> Field { + self.value + } + + fn override_counter(self) -> u32 { + self.override_counter + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr index a9e9e772f59a..db3a8cddfb0b 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -29,7 +29,7 @@ use dep::types::{ }, mocked::{AggregationObject, Proof}, partial_state_reference::PartialStateReference, public_data_tree_leaf::PublicDataTreeLeaf, - public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage, + public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage, traits::is_empty, utils::{field::{full_field_less_than, full_field_greater_than}, uint256::U256} }; @@ -66,6 +66,8 @@ impl BaseRollupInputs { == self.constants.global_variables.version, "kernel version does not match the rollup version" ); + self.validate_kernel_start_state(); + let rollup_validation_requests = self.kernel_data.public_inputs.rollup_validation_requests; // Verify the max block number @@ -177,18 +179,22 @@ impl BaseRollupInputs { calculate_subtree_root(leaves.map(|leaf:NullifierLeafPreimage| leaf.hash())) } - fn validate_and_process_public_state(self) -> AppendOnlyTreeSnapshot { - // TODO(#2521) - data read validation should happen against the current state of the tx and not the start state. - // Blocks all interesting usecases that read and write to the same public state in the same tx. - // https://aztecprotocol.slack.com/archives/C02M7VC7TN0/p1695809629015719?thread_ts=1695653252.007339&cid=C02M7VC7TN0 - - // Process public data reads and public data update requests for left input - // validate_public_data_reads( - // self.start_public_data_tree_root, - // self.kernel_data[0].public_inputs.end.public_data_reads, - // 0, - // self.new_public_data_reads_sibling_paths); + fn validate_kernel_start_state(self) { + let kernel_state = self.kernel_data.public_inputs.start_state; + if !is_empty(kernel_state) { + assert( + kernel_state.note_hash_tree.eq(self.start.note_hash_tree), "Mismatch start state for note hash tree" + ); + assert( + kernel_state.nullifier_tree.eq(self.start.nullifier_tree), "Mismatch start state for nullifier tree" + ); + assert( + kernel_state.public_data_tree.eq(self.start.public_data_tree), "Mismatch start state for public data tree" + ); + } + } + fn validate_and_process_public_state(self) -> AppendOnlyTreeSnapshot { let end_public_data_tree_snapshot = insert_public_data_update_requests( self.start.public_data_tree, self.kernel_data.public_inputs.end.public_data_update_requests.map( @@ -318,43 +324,6 @@ fn insert_public_data_update_requests( ) } -fn validate_public_data_reads( - tree_root: Field, - public_data_reads: [PublicDataRead; MAX_PUBLIC_DATA_READS_PER_TX], - public_data_reads_preimages: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX], - public_data_reads_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX] -) { - for i in 0..MAX_PUBLIC_DATA_READS_PER_TX { - let read = public_data_reads[i]; - let low_preimage = public_data_reads_preimages[i]; - let witness = public_data_reads_witnesses[i]; - - let is_low_empty = low_preimage.is_empty(); - let is_exact = low_preimage.slot == read.leaf_slot; - - let is_less_than_slot = full_field_less_than(low_preimage.slot, read.leaf_slot); - let is_next_greater_than = full_field_less_than(read.leaf_slot, low_preimage.next_slot); - let is_in_range = is_less_than_slot - & (is_next_greater_than | ((low_preimage.next_index == 0) & (low_preimage.next_slot == 0))); - - if (!read.is_empty()) { - assert(!is_low_empty, "public data read is not empty but low preimage is empty"); - if is_in_range { - assert_eq(read.value, 0, "low leaf for public data read is in range but value is not zero"); - } else { - assert(is_exact, "low leaf for public data read is invalid"); - assert_eq(read.value, low_preimage.value, "low leaf for public data has different value"); - } - assert_check_membership( - low_preimage.hash(), - witness.leaf_index, - witness.sibling_path, - tree_root - ); - } - } -} - #[test] fn consistent_not_hash_subtree_width() { assert_eq( diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr index d4576c369db4..23762fd5bf31 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis.nr @@ -41,4 +41,4 @@ mod private_circuit_public_inputs; mod gas_fees; mod gas_settings; -mod gas_used; +mod gas; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr index da9ad715af60..2e23a804ce18 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr @@ -1,8 +1,9 @@ use crate::{ + hash::compute_tx_logs_hash, abis::{ accumulated_data::public_accumulated_data::PublicAccumulatedData, public_data_update_request::PublicDataUpdateRequest, - side_effect::{SideEffect, SideEffectLinkedToNoteHash}, gas_used::GasUsed + side_effect::{SideEffect, SideEffectLinkedToNoteHash}, gas::Gas }, constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, @@ -26,19 +27,22 @@ struct CombinedAccumulatedData { public_data_update_requests: [PublicDataUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - gas_used: GasUsed, + gas_used: Gas, } impl CombinedAccumulatedData { - pub fn recombine(non_revertible: PublicAccumulatedData, revertible: PublicAccumulatedData) -> Self { + pub fn combine(non_revertible: PublicAccumulatedData, revertible: PublicAccumulatedData) -> Self { + // TODO(Miranda): Hash here or elsewhere? + let encrypted_logs_hash = compute_tx_logs_hash(array_merge(non_revertible.encrypted_logs_hashes, revertible.encrypted_logs_hashes)); + let unencrypted_logs_hash = compute_tx_logs_hash(array_merge(non_revertible.unencrypted_logs_hashes, revertible.unencrypted_logs_hashes)); CombinedAccumulatedData { new_note_hashes: array_merge(non_revertible.new_note_hashes, revertible.new_note_hashes).map(|n: SideEffect| n.value), new_nullifiers: array_merge(non_revertible.new_nullifiers, revertible.new_nullifiers).map(|n: SideEffectLinkedToNoteHash| n.value), new_l2_to_l1_msgs: revertible.new_l2_to_l1_msgs, - encrypted_logs_hash: revertible.encrypted_logs_hash, - unencrypted_logs_hash: revertible.unencrypted_logs_hash, - encrypted_log_preimages_length: revertible.encrypted_log_preimages_length, - unencrypted_log_preimages_length: revertible.unencrypted_log_preimages_length, + encrypted_logs_hash: encrypted_logs_hash, + unencrypted_logs_hash: unencrypted_logs_hash, + encrypted_log_preimages_length: non_revertible.encrypted_log_preimages_length + revertible.encrypted_log_preimages_length, + unencrypted_log_preimages_length: non_revertible.unencrypted_log_preimages_length + revertible.unencrypted_log_preimages_length, public_data_update_requests: array_merge( non_revertible.public_data_update_requests, revertible.public_data_update_requests @@ -59,7 +63,7 @@ impl Empty for CombinedAccumulatedData { encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, public_data_update_requests: [PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - gas_used: GasUsed::empty() + gas_used: Gas::empty() } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr index 2d3304491ddb..2fc4064125ab 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr @@ -1,7 +1,8 @@ -use crate::{abis::{call_request::CallRequest, gas_used::GasUsed, side_effect::{SideEffect, SideEffectLinkedToNoteHash}}}; +use crate::{abis::{call_request::CallRequest, gas::Gas, side_effect::{SideEffect, SideEffectLinkedToNoteHash}}}; use crate::constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX }; struct PrivateAccumulatedData { @@ -9,8 +10,8 @@ struct PrivateAccumulatedData { new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], - encrypted_logs_hash: Field, - unencrypted_logs_hash: Field, + encrypted_logs_hashes: [SideEffect; MAX_ENCRYPTED_LOGS_PER_TX], + unencrypted_logs_hashes: [SideEffect; MAX_UNENCRYPTED_LOGS_PER_TX], // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the // variable-length data. @@ -20,5 +21,5 @@ struct PrivateAccumulatedData { private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], public_call_stack: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], - gas_used: GasUsed, + gas_used: Gas, } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr index 078888372fc8..464fdda2079f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr @@ -1,6 +1,7 @@ use crate::{ + hash::compute_tx_logs_hash, abis::{ - gas_used::GasUsed, + gas::Gas, accumulated_data::{ combined_accumulated_data::CombinedAccumulatedData, private_accumulated_data::PrivateAccumulatedData, public_accumulated_data::PublicAccumulatedData, @@ -12,7 +13,7 @@ use crate::{ constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX }, traits::Empty }; @@ -22,8 +23,8 @@ struct PrivateAccumulatedDataBuilder { new_nullifiers: BoundedVec, new_l2_to_l1_msgs: BoundedVec, - encrypted_logs_hash: Field, - unencrypted_logs_hash: Field, + encrypted_logs_hashes: BoundedVec, + unencrypted_logs_hashes: BoundedVec, // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the // variable-length data. @@ -33,7 +34,7 @@ struct PrivateAccumulatedDataBuilder { private_call_stack: BoundedVec, public_call_stack: BoundedVec, - gas_used: GasUsed + gas_used: Gas } impl PrivateAccumulatedDataBuilder { @@ -42,8 +43,8 @@ impl PrivateAccumulatedDataBuilder { new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_logs_hashes: self.encrypted_logs_hashes.storage, + unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, encrypted_log_preimages_length: self.encrypted_log_preimages_length, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, private_call_stack: self.private_call_stack.storage, @@ -53,12 +54,16 @@ impl PrivateAccumulatedDataBuilder { } pub fn to_combined(self) -> CombinedAccumulatedData { + // TODO(Miranda): Hash here or elsewhere? + let encrypted_logs_hash = compute_tx_logs_hash(self.encrypted_logs_hashes.storage); + let unencrypted_logs_hash = compute_tx_logs_hash(self.unencrypted_logs_hashes.storage); + CombinedAccumulatedData { new_note_hashes: self.new_note_hashes.storage.map(|n: SideEffect| n.value), new_nullifiers: self.new_nullifiers.storage.map(|n: SideEffectLinkedToNoteHash| n.value), new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_logs_hash: encrypted_logs_hash, + unencrypted_logs_hash: unencrypted_logs_hash, encrypted_log_preimages_length: self.encrypted_log_preimages_length, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, public_data_update_requests: [PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], @@ -81,6 +86,7 @@ impl PrivateAccumulatedDataBuilder { revertible_builder.new_note_hashes.push(note_hash); } } + for i in 0..MAX_NEW_NULLIFIERS_PER_TX { let nullifier = self.new_nullifiers.storage[i]; if nullifier.counter < min_revertible_side_effect_counter { @@ -99,11 +105,28 @@ impl PrivateAccumulatedDataBuilder { } } + for i in 0..MAX_ENCRYPTED_LOGS_PER_TX { + let encrypted_logs_hash = self.encrypted_logs_hashes.storage[i]; + if encrypted_logs_hash.counter < min_revertible_side_effect_counter { + non_revertible_builder.encrypted_logs_hashes.push(encrypted_logs_hash); + } else { + revertible_builder.encrypted_logs_hashes.push(encrypted_logs_hash); + } + } + + for i in 0..MAX_UNENCRYPTED_LOGS_PER_TX { + let unencrypted_logs_hash = self.unencrypted_logs_hashes.storage[i]; + if unencrypted_logs_hash.counter < min_revertible_side_effect_counter { + non_revertible_builder.unencrypted_logs_hashes.push(unencrypted_logs_hash); + } else { + revertible_builder.unencrypted_logs_hashes.push(unencrypted_logs_hash); + } + } + revertible_builder.new_l2_to_l1_msgs = self.new_l2_to_l1_msgs; - revertible_builder.encrypted_logs_hash = self.encrypted_logs_hash; - revertible_builder.unencrypted_logs_hash = self.unencrypted_logs_hash; + // TODO(1165): Once we have individual lens, split here revertible_builder.encrypted_log_preimages_length = self.encrypted_log_preimages_length; - revertible_builder.unencrypted_log_preimages_length= self.unencrypted_log_preimages_length; + revertible_builder.unencrypted_log_preimages_length = self.unencrypted_log_preimages_length; (non_revertible_builder.finish(), revertible_builder.finish()) } @@ -198,13 +221,13 @@ impl Empty for PrivateAccumulatedDataBuilder { new_note_hashes: BoundedVec::new(), new_nullifiers: BoundedVec::new(), new_l2_to_l1_msgs: BoundedVec::new(), - encrypted_logs_hash: 0, - unencrypted_logs_hash: 0, + encrypted_logs_hashes: BoundedVec::new(), + unencrypted_logs_hashes: BoundedVec::new(), encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, private_call_stack: BoundedVec::new(), public_call_stack: BoundedVec::new(), - gas_used: GasUsed::empty(), + gas_used: Gas::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr index e1e472a0e2f1..595f1aa8193c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr @@ -1,11 +1,12 @@ use crate::{ abis::{ - call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, gas_used::GasUsed, + call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, gas::Gas, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX }, traits::Empty }; @@ -15,8 +16,8 @@ struct PublicAccumulatedData { new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], - encrypted_logs_hash: Field, - unencrypted_logs_hash: Field, + encrypted_logs_hashes: [SideEffect; MAX_ENCRYPTED_LOGS_PER_TX], + unencrypted_logs_hashes: [SideEffect; MAX_UNENCRYPTED_LOGS_PER_TX], // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the // variable-length data. @@ -27,7 +28,7 @@ struct PublicAccumulatedData { public_call_stack: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], - gas_used: GasUsed, + gas_used: Gas, } impl Empty for PublicAccumulatedData { @@ -36,13 +37,13 @@ impl Empty for PublicAccumulatedData { new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_TX], new_l2_to_l1_msgs: [0; MAX_NEW_L2_TO_L1_MSGS_PER_TX], - encrypted_logs_hash: 0, - unencrypted_logs_hash: 0, + encrypted_logs_hashes: [SideEffect::empty(); MAX_ENCRYPTED_LOGS_PER_TX], + unencrypted_logs_hashes: [SideEffect::empty(); MAX_UNENCRYPTED_LOGS_PER_TX], encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, public_data_update_requests: [PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], public_call_stack: [CallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], - gas_used: GasUsed::empty(), + gas_used: Gas::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr index 66cc145413f7..e66601a34181 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr @@ -1,12 +1,13 @@ use crate::{ abis::{ - gas_used::GasUsed, accumulated_data::public_accumulated_data::PublicAccumulatedData, + gas::Gas, accumulated_data::public_accumulated_data::PublicAccumulatedData, call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX }, traits::Empty }; @@ -16,8 +17,8 @@ struct PublicAccumulatedDataBuilder { new_nullifiers: BoundedVec, new_l2_to_l1_msgs: BoundedVec, - encrypted_logs_hash: Field, - unencrypted_logs_hash: Field, + encrypted_logs_hashes: BoundedVec, + unencrypted_logs_hashes: BoundedVec, // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the // variable-length data. @@ -28,7 +29,7 @@ struct PublicAccumulatedDataBuilder { public_call_stack: BoundedVec, - gas_used: GasUsed, + gas_used: Gas, } impl PublicAccumulatedDataBuilder { @@ -37,8 +38,8 @@ impl PublicAccumulatedDataBuilder { new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_logs_hashes: self.encrypted_logs_hashes.storage, + unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, encrypted_log_preimages_length: self.encrypted_log_preimages_length, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, public_data_update_requests: self.public_data_update_requests.storage, @@ -54,13 +55,13 @@ impl Empty for PublicAccumulatedDataBuilder { new_note_hashes: BoundedVec::new(), new_nullifiers: BoundedVec::new(), new_l2_to_l1_msgs: BoundedVec::new(), - encrypted_logs_hash: 0, - unencrypted_logs_hash: 0, + encrypted_logs_hashes: BoundedVec::new(), + unencrypted_logs_hashes: BoundedVec::new(), encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, public_data_update_requests: BoundedVec::new(), public_call_stack: BoundedVec::new(), - gas_used: GasUsed::empty(), + gas_used: Gas::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr index ab2c27b2b707..870e4b80df5d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr @@ -2,7 +2,7 @@ use crate::{ abis::function_selector::FunctionSelector, address::{EthAddress, AztecAddress}, constants::{CALL_CONTEXT_LENGTH, GENERATOR_INDEX__CALL_CONTEXT}, hash::pedersen_hash, traits::{Deserialize, Hash, Serialize, Empty}, abis::side_effect::Ordered, - abis::gas_settings::GasSettings, utils::reader::Reader + abis::{gas_settings::GasSettings, gas::Gas}, utils::reader::Reader }; // docs:start:call-context @@ -10,8 +10,8 @@ struct CallContext { msg_sender : AztecAddress, storage_contract_address : AztecAddress, portal_contract_address : EthAddress, - function_selector : FunctionSelector, + gas_left: Gas, is_delegate_call : bool, is_static_call : bool, @@ -53,6 +53,7 @@ impl Serialize for CallContext { serialized.push(self.storage_contract_address.to_field()); serialized.push(self.portal_contract_address.to_field()); serialized.push(self.function_selector.to_field()); + serialized.extend_from_array(self.gas_left.serialize()); serialized.push(self.is_delegate_call as Field); serialized.push(self.is_static_call as Field); serialized.push(self.side_effect_counter as Field); @@ -71,6 +72,7 @@ impl Deserialize for CallContext { storage_contract_address: AztecAddress::from_field(reader.read()), portal_contract_address: EthAddress::from_field(reader.read()), function_selector: FunctionSelector::from_field(reader.read()), + gas_left: reader.read_struct(Gas::deserialize), is_delegate_call: reader.read() as bool, is_static_call: reader.read() as bool, side_effect_counter: reader.read() as u32, @@ -87,6 +89,7 @@ impl Empty for CallContext { storage_contract_address: AztecAddress::empty(), portal_contract_address: EthAddress::empty(), function_selector: FunctionSelector::empty(), + gas_left: Gas::empty(), is_delegate_call: false, is_static_call: false, side_effect_counter: 0, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas.nr new file mode 100644 index 000000000000..d4c6297b98b3 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas.nr @@ -0,0 +1,58 @@ +use crate::{ + abis::function_selector::FunctionSelector, address::{EthAddress, AztecAddress}, + constants::GAS_LENGTH, hash::pedersen_hash, traits::{Deserialize, Hash, Serialize, Empty}, + abis::side_effect::Ordered, utils::reader::Reader +}; + +struct Gas { + da_gas: u32, + l1_gas: u32, + l2_gas: u32, +} + +impl Gas { + pub fn new(da_gas: u32, l1_gas: u32, l2_gas: u32) -> Self { + Self { da_gas, l1_gas, l2_gas } + } + + fn add(self, other: Gas) -> Self { + Gas::new( + self.da_gas + other.da_gas, + self.l1_gas + other.l1_gas, + self.l2_gas + other.l2_gas + ) + } + + fn sub(self, other: Gas) -> Self { + Gas::new( + self.da_gas - other.da_gas, + self.l1_gas - other.l1_gas, + self.l2_gas - other.l2_gas + ) + } +} + +impl Serialize for Gas { + fn serialize(self) -> [Field; GAS_LENGTH] { + [self.da_gas as Field, self.l1_gas as Field, self.l2_gas as Field] + } +} + +impl Deserialize for Gas { + fn deserialize(serialized: [Field; GAS_LENGTH]) -> Gas { + Gas::new(serialized[0] as u32, serialized[1] as u32, serialized[2] as u32) + } +} + +impl Eq for Gas { + fn eq(self, other : Gas) -> bool { + (self.da_gas == other.da_gas) & (self.l1_gas == other.l1_gas) & (self.l2_gas == other.l2_gas) + } +} + +impl Empty for Gas { + fn empty() -> Self { + Gas::new(0, 0, 0) + } +} + diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr index d2fcb6c451ce..f50b22528d91 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr @@ -1,5 +1,5 @@ use crate::{ - abis::function_selector::FunctionSelector, address::{EthAddress, AztecAddress}, + abis::function_selector::FunctionSelector, address::{EthAddress, AztecAddress}, abis::gas::Gas, constants::{GAS_SETTINGS_LENGTH, DIMENSION_GAS_SETTINGS_LENGTH}, hash::pedersen_hash, traits::{Deserialize, Hash, Serialize, Empty}, abis::side_effect::Ordered, utils::reader::Reader }; @@ -20,6 +20,16 @@ impl GasSettings { ) -> Self { Self { da, l1, l2, inclusion_fee } } + + fn get_gas_limits(self) -> Gas { + Gas { da_gas: self.da.gas_limit, l1_gas: self.l1.gas_limit, l2_gas: self.l2.gas_limit } + } +} + +impl Eq for GasSettings { + fn eq(self, other: Self) -> bool { + (self.da == other.da) & (self.l1 == other.l1) & (self.l2 == other.l2) & (self.inclusion_fee == other.inclusion_fee) + } } impl Empty for GasSettings { @@ -65,11 +75,18 @@ struct DimensionGasSettings { } impl DimensionGasSettings { - fn new(gas_limit: u32, teardown_gas_limit: u32, max_fee_per_gas: Field) -> Self { + pub fn new(gas_limit: u32, teardown_gas_limit: u32, max_fee_per_gas: Field) -> Self { Self { gas_limit, teardown_gas_limit, max_fee_per_gas } } } +impl Eq for DimensionGasSettings { + fn eq(self, other: Self) -> bool { + (self.gas_limit == other.gas_limit) & (self.teardown_gas_limit == other.teardown_gas_limit) & (self.max_fee_per_gas == other.max_fee_per_gas) + } + +} + impl Serialize for DimensionGasSettings { fn serialize(self) -> [Field; DIMENSION_GAS_SETTINGS_LENGTH] { [ diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_used.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_used.nr deleted file mode 100644 index 9ac8a02520f6..000000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_used.nr +++ /dev/null @@ -1,49 +0,0 @@ -use crate::{ - abis::function_selector::FunctionSelector, address::{EthAddress, AztecAddress}, - constants::GAS_USED_LENGTH, hash::pedersen_hash, traits::{Deserialize, Hash, Serialize, Empty}, - abis::side_effect::Ordered, utils::reader::Reader -}; - -struct GasUsed { - da_gas: Field, - l1_gas: Field, - l2_gas: Field, -} - -impl GasUsed { - fn new(da_gas: Field, l1_gas: Field, l2_gas: Field) -> Self { - Self { da_gas, l1_gas, l2_gas } - } - - fn add(self, other: GasUsed) -> Self { - GasUsed::new( - self.da_gas + other.da_gas, - self.l1_gas + other.l1_gas, - self.l2_gas + other.l2_gas - ) - } -} - -impl Serialize for GasUsed { - fn serialize(self) -> [Field; GAS_USED_LENGTH] { - [self.da_gas, self.l1_gas, self.l2_gas] - } -} - -impl Deserialize for GasUsed { - fn deserialize(serialized: [Field; GAS_USED_LENGTH]) -> GasUsed { - GasUsed::new(serialized[0], serialized[1], serialized[2]) - } -} - -impl Eq for GasUsed { - fn eq(self, other : GasUsed) -> bool { - (self.da_gas == other.da_gas) & (self.l1_gas == other.l1_gas) & (self.l2_gas == other.l2_gas) - } -} - -impl Empty for GasUsed { - fn empty() -> Self { - GasUsed::new(0, 0, 0) - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr index b15b68d23654..41100691cbc1 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr @@ -1,6 +1,9 @@ -use crate::abis::{ +use crate::{ + abis::{ accumulated_data::CombinedAccumulatedData, combined_constant_data::CombinedConstantData, validation_requests::RollupValidationRequests +}, + partial_state_reference::PartialStateReference }; use crate::mocked::AggregationObject; @@ -9,5 +12,6 @@ struct KernelCircuitPublicInputs { rollup_validation_requests: RollupValidationRequests, end: CombinedAccumulatedData, constants: CombinedConstantData, + start_state: PartialStateReference, revert_code: u8, } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr index 5aa04bfc44f4..b4fc52176216 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr @@ -8,8 +8,7 @@ use crate::{ }, validation_requests::validation_requests_builder::ValidationRequestsBuilder }, -mocked::AggregationObject, -traits::Empty + mocked::AggregationObject, partial_state_reference::PartialStateReference, traits::Empty }; struct PrivateKernelCircuitPublicInputsBuilder { @@ -37,6 +36,7 @@ impl PrivateKernelCircuitPublicInputsBuilder { rollup_validation_requests: self.validation_requests.to_rollup(), end: self.end.to_combined(), constants: self.constants, + start_state: PartialStateReference::empty(), revert_code: 0 } } @@ -65,4 +65,4 @@ impl Empty for PrivateKernelCircuitPublicInputsBuilder { constants: CombinedConstantData::empty(), } } -} \ No newline at end of file +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr index 6d3dc6fefc40..5a0ff151e9ba 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr @@ -2,14 +2,10 @@ use crate::{ abis::{ accumulated_data::{CombinedAccumulatedData, PublicAccumulatedDataBuilder}, combined_constant_data::CombinedConstantData, - kernel_circuit_public_inputs::{ - kernel_circuit_public_inputs::KernelCircuitPublicInputs, - public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs -}, + kernel_circuit_public_inputs::{public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs}, validation_requests::ValidationRequestsBuilder }, -mocked::AggregationObject, -traits::Empty + mocked::AggregationObject, traits::Empty }; struct PublicKernelCircuitPublicInputsBuilder { @@ -35,17 +31,6 @@ impl PublicKernelCircuitPublicInputsBuilder { revert_code: self.revert_code } } - - pub fn finish_tail(self) -> KernelCircuitPublicInputs { - KernelCircuitPublicInputs { - aggregation_object: self.aggregation_object, - rollup_validation_requests: self.validation_requests.to_rollup(), - // TODO: Sort by counters. - end: CombinedAccumulatedData::recombine(self.end_non_revertible.finish(), self.end.finish()), - constants: self.constants, - revert_code: self.revert_code - } - } } impl Empty for PublicKernelCircuitPublicInputsBuilder { @@ -59,4 +44,4 @@ impl Empty for PublicKernelCircuitPublicInputsBuilder { revert_code: 0 as u8, } } -} \ No newline at end of file +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr index e74c6fd8e0d8..45b7f67c493e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_stack_item.nr @@ -85,6 +85,6 @@ fn empty_hash() { let hash = item.hash(); // Value from private_call_stack_item.test.ts "computes empty item hash" test - let test_data_empty_hash = 0x229caf5ebf8961d7cbfdf2f7a5db62810d130b598900a0be1137394a43371bc6; + let test_data_empty_hash = 0x24185d8e88fe796dec6e400f3d6c7572cefd85cea80591f268f08a9350992c48; assert_eq(hash, test_data_empty_hash); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr index b985d0b236a5..09fbc60463e6 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr @@ -9,7 +9,8 @@ use crate::{ MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, - PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS + PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, + GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS, MAX_ENCRYPTED_LOGS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL }, header::Header, hash::pedersen_hash, messaging::l2_to_l1_message::L2ToL1Message, traits::{Deserialize, Hash, Serialize, Empty}, utils::reader::Reader @@ -37,8 +38,8 @@ struct PrivateCircuitPublicInputs { start_side_effect_counter : u32, end_side_effect_counter : u32, - encrypted_logs_hash: Field, - unencrypted_logs_hash: Field, + encrypted_logs_hashes: [SideEffect; MAX_ENCRYPTED_LOGS_PER_CALL], + unencrypted_logs_hashes: [SideEffect; MAX_UNENCRYPTED_LOGS_PER_CALL], // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the // variable-length data. @@ -71,8 +72,8 @@ impl Eq for PrivateCircuitPublicInputs { (self.new_l2_to_l1_msgs == other.new_l2_to_l1_msgs) & (self.start_side_effect_counter == other.start_side_effect_counter) & (self.end_side_effect_counter == other.end_side_effect_counter) & - (self.encrypted_logs_hash == other.encrypted_logs_hash) & - (self.unencrypted_logs_hash == other.unencrypted_logs_hash) & + (self.encrypted_logs_hashes == other.encrypted_logs_hashes) & + (self.unencrypted_logs_hashes == other.unencrypted_logs_hashes) & (self.encrypted_log_preimages_length == other.encrypted_log_preimages_length) & (self.unencrypted_log_preimages_length == other.unencrypted_log_preimages_length) & self.historical_header.eq(other.historical_header) & @@ -92,30 +93,34 @@ impl Serialize for PrivateCircuitPublicInp fields.extend_from_array(self.max_block_number.serialize()); - for i in 0..MAX_NOTE_HASH_READ_REQUESTS_PER_CALL{ + for i in 0..self.note_hash_read_requests.len() { fields.extend_from_array(self.note_hash_read_requests[i].serialize()); } - for i in 0..MAX_NULLIFIER_READ_REQUESTS_PER_CALL{ + for i in 0..self.nullifier_read_requests.len() { fields.extend_from_array(self.nullifier_read_requests[i].serialize()); } - for i in 0..MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL{ + for i in 0..self.nullifier_key_validation_requests.len() { fields.extend_from_array(self.nullifier_key_validation_requests[i].serialize()); } - for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL{ + for i in 0..self.new_note_hashes.len() { fields.extend_from_array(self.new_note_hashes[i].serialize()); } - for i in 0..MAX_NEW_NULLIFIERS_PER_CALL{ + for i in 0..self.new_nullifiers.len() { fields.extend_from_array(self.new_nullifiers[i].serialize()); } fields.extend_from_array(self.private_call_stack_hashes); fields.extend_from_array(self.public_call_stack_hashes); - for i in 0..MAX_NEW_L2_TO_L1_MSGS_PER_CALL { + for i in 0..self.new_l2_to_l1_msgs.len() { fields.extend_from_array(self.new_l2_to_l1_msgs[i].serialize()); } fields.push(self.start_side_effect_counter as Field); fields.push(self.end_side_effect_counter as Field); - fields.push(self.encrypted_logs_hash); - fields.push(self.unencrypted_logs_hash); + for i in 0..self.encrypted_logs_hashes.len() { + fields.extend_from_array(self.encrypted_logs_hashes[i].serialize()); + } + for i in 0..self.unencrypted_logs_hashes.len() { + fields.extend_from_array(self.unencrypted_logs_hashes[i].serialize()); + } fields.push(self.encrypted_log_preimages_length); fields.push(self.unencrypted_log_preimages_length); fields.extend_from_array(self.historical_header.serialize()); @@ -148,8 +153,8 @@ impl Deserialize for PrivateCircuitPublicI new_l2_to_l1_msgs: reader.read_struct_array(L2ToL1Message::deserialize, [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL]), start_side_effect_counter: reader.read() as u32, end_side_effect_counter: reader.read() as u32, - encrypted_logs_hash: reader.read() as Field, - unencrypted_logs_hash: reader.read() as Field, + encrypted_logs_hashes: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_ENCRYPTED_LOGS_PER_CALL]), + unencrypted_logs_hashes: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL]), encrypted_log_preimages_length: reader.read(), unencrypted_log_preimages_length: reader.read(), historical_header: reader.read_struct(Header::deserialize), @@ -187,8 +192,8 @@ impl Empty for PrivateCircuitPublicInputs { new_l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL], start_side_effect_counter : 0 as u32, end_side_effect_counter : 0 as u32, - encrypted_logs_hash: 0, - unencrypted_logs_hash: 0, + encrypted_logs_hashes: [SideEffect::empty(); MAX_ENCRYPTED_LOGS_PER_CALL], + unencrypted_logs_hashes: [SideEffect::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL], encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, historical_header: Header::empty(), @@ -210,8 +215,7 @@ fn serialization_of_empty() { fn empty_hash() { let inputs = PrivateCircuitPublicInputs::empty(); let hash = inputs.hash(); - // Value from private_circuit_public_inputs.test.ts "computes empty item hash" test - let test_data_empty_hash = 0x13ba2af75e4afaa4e52dd1afa083e87706cdbab1a33442025dc3a9bbb546d207; + let test_data_empty_hash = 0x24ea9ab3fc039778bef8e7212f6a09feec1019db19b449333b523a08b812ee88; assert_eq(hash, test_data_empty_hash); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr index 76f1c28c4952..7bafc07b37da 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item.nr @@ -69,7 +69,7 @@ mod tests { let call_stack_item = PublicCallStackItem { contract_address, public_inputs, is_execution_request: true, function_data }; // Value from public_call_stack_item.test.ts "Computes a callstack item request hash" test - let test_data_call_stack_item_request_hash = 0x151bc9ee42eb63112fb2a350dcaa33c4c4b81cc37ded8773e785f47029f35983; + let test_data_call_stack_item_request_hash = 0x134d01b778664dbc1ffa953008ce28f72b0cb258533776f10df59a59d791e972; assert_eq(call_stack_item.hash(), test_data_call_stack_item_request_hash); } @@ -87,7 +87,7 @@ mod tests { let call_stack_item = PublicCallStackItem { contract_address, public_inputs, is_execution_request: false, function_data }; // Value from public_call_stack_item.test.ts "Computes a callstack item hash" test - let test_data_call_stack_item_hash = 0x1a7b9d0cd965f512a3b3ed70333198a2a69bd4f9e70be68379c54e68a7b07a4c; + let test_data_call_stack_item_hash = 0x0c0d60d424315af5f106a802b250c27c613a9ec1c0f583c6ad806cf22fe66a13; assert_eq(call_stack_item.hash(), test_data_call_stack_item_hash); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_circuit_public_inputs.nr index 3a6182880db8..ca5dc4742f3e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_circuit_public_inputs.nr @@ -1,22 +1,23 @@ use crate::{ abis::{ call_context::CallContext, read_request::ReadRequest, - side_effect::{SideEffect, SideEffectLinkedToNoteHash} + side_effect::{SideEffect, SideEffectLinkedToNoteHash}, gas::Gas }, address::AztecAddress, constants::{ MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS, - PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, + GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS, PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH, + MAX_UNENCRYPTED_LOGS_PER_CALL }, contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, hash::pedersen_hash, header::Header, messaging::l2_to_l1_message::L2ToL1Message, traits::{Hash, Serialize, Deserialize, Empty}, utils::reader::Reader }; -struct PublicCircuitPublicInputs{ +struct PublicCircuitPublicInputs { call_context: CallContext, args_hash: Field, @@ -36,7 +37,7 @@ struct PublicCircuitPublicInputs{ start_side_effect_counter: u32, end_side_effect_counter: u32, - unencrypted_logs_hash: Field, + unencrypted_logs_hashes: [SideEffect; MAX_UNENCRYPTED_LOGS_PER_CALL], // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the // variable-length data. @@ -49,6 +50,9 @@ struct PublicCircuitPublicInputs{ prover_address: AztecAddress, revert_code: u8, + + // gas left after execution is completed + gas_left: Gas, } impl Eq for PublicCircuitPublicInputs { @@ -90,11 +94,14 @@ impl Serialize for PublicCircuitPublicInput fields.push(self.start_side_effect_counter as Field); fields.push(self.end_side_effect_counter as Field); - fields.push(self.unencrypted_logs_hash); + for i in 0..MAX_UNENCRYPTED_LOGS_PER_CALL{ + fields.extend_from_array(self.unencrypted_logs_hashes[i].serialize()); + } fields.push(self.unencrypted_log_preimages_length); fields.extend_from_array(self.historical_header.serialize()); fields.push(self.prover_address.to_field()); fields.push(self.revert_code as Field); + fields.extend_from_array(self.gas_left.serialize()); fields.storage } } @@ -117,11 +124,12 @@ impl Deserialize for PublicCircuitPublicInp new_l2_to_l1_msgs: reader.read_struct_array(L2ToL1Message::deserialize, [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL]), start_side_effect_counter: reader.read() as u32, end_side_effect_counter: reader.read() as u32, - unencrypted_logs_hash: reader.read() as Field, + unencrypted_logs_hashes: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL]), unencrypted_log_preimages_length: reader.read(), historical_header: reader.read_struct(Header::deserialize), prover_address: reader.read_struct(AztecAddress::deserialize), revert_code: reader.read() as u8, + gas_left: reader.read_struct(Gas::deserialize), }; reader.finish(); @@ -151,11 +159,12 @@ impl Empty for PublicCircuitPublicInputs { new_l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL], start_side_effect_counter: 0 as u32, end_side_effect_counter: 0 as u32, - unencrypted_logs_hash: 0, + unencrypted_logs_hashes: [SideEffect::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL], unencrypted_log_preimages_length: 0, historical_header: Header::empty(), prover_address: AztecAddress::zero(), revert_code: 0 as u8, + gas_left: Gas::empty(), } } } @@ -174,6 +183,6 @@ fn empty_hash() { let hash = inputs.hash(); // Value from public_circuit_public_inputs.test.ts "computes empty item hash" test - let test_data_empty_hash = 0x2745ec62624afeb19b86af3d440db1f8c3432e1d17a074c75cb8f44999fd3fae; + let test_data_empty_hash = 0x1092820bc987359300ff136abf020d58218e1b3484e03d756c76e81ac56ccbf7; assert_eq(hash, test_data_empty_hash); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr index 1d6acb753f11..1a1e221405c5 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr @@ -1,10 +1,10 @@ use crate::{ abis::side_effect::{OrderedValue, ContractScopedOrderedValue}, - traits::{Empty, Serialize, Deserialize}, address::AztecAddress + traits::{Empty, Serialize, Deserialize}, address::AztecAddress, + constants::READ_REQUEST_LENGTH, }; use dep::std::cmp::Eq; -global READ_REQUEST_SERIALIZED_LEN = 2; global READ_REQUEST_CONTEXT_SERIALIZED_LEN = 3; struct ReadRequest { @@ -37,14 +37,14 @@ impl Empty for ReadRequest { } } -impl Serialize for ReadRequest { - fn serialize(self) -> [Field; READ_REQUEST_SERIALIZED_LEN] { +impl Serialize for ReadRequest { + fn serialize(self) -> [Field; READ_REQUEST_LENGTH] { [self.value, self.counter as Field] } } -impl Deserialize for ReadRequest { - fn deserialize(values: [Field; READ_REQUEST_SERIALIZED_LEN]) -> Self { +impl Deserialize for ReadRequest { + fn deserialize(values: [Field; READ_REQUEST_LENGTH]) -> Self { Self { value: values[0], counter: values[1] as u32, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr index d7e4cca3fe8f..63448cc0ebe3 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr @@ -1,11 +1,10 @@ use crate::{ address::AztecAddress, constants::GENERATOR_INDEX__SIDE_EFFECT, - traits::{Empty, Hash, Serialize, Deserialize} + traits::{Empty, Hash, Serialize, Deserialize}, + constants::{SIDE_EFFECT_LENGTH, SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH}, }; use dep::std::cmp::Eq; -global SIDE_EFFECT_SERIALIZED_LEN = 2; - trait Ordered { fn counter(self) -> u32; } @@ -64,14 +63,14 @@ impl Hash for SideEffect { } } -impl Serialize for SideEffect { - fn serialize(self) -> [Field; SIDE_EFFECT_SERIALIZED_LEN] { +impl Serialize for SideEffect { + fn serialize(self) -> [Field; SIDE_EFFECT_LENGTH] { [self.value, self.counter as Field] } } -impl Deserialize for SideEffect { - fn deserialize(values: [Field; SIDE_EFFECT_SERIALIZED_LEN]) -> Self { +impl Deserialize for SideEffect { + fn deserialize(values: [Field; SIDE_EFFECT_LENGTH]) -> Self { Self { value: values[0], counter: values[1] as u32, @@ -79,7 +78,7 @@ impl Deserialize for SideEffect { } } -struct SideEffectLinkedToNoteHash{ +struct SideEffectLinkedToNoteHash { value: Field, note_hash: Field, counter: u32, @@ -126,14 +125,14 @@ impl Hash for SideEffectLinkedToNoteHash { } } -impl Serialize<3> for SideEffectLinkedToNoteHash { - fn serialize(self) -> [Field; 3] { +impl Serialize for SideEffectLinkedToNoteHash { + fn serialize(self) -> [Field; SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH] { [self.value, self.note_hash, self.counter as Field] } } -impl Deserialize<3> for SideEffectLinkedToNoteHash { - fn deserialize(values: [Field; 3]) -> Self { +impl Deserialize for SideEffectLinkedToNoteHash { + fn deserialize(values: [Field; SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH]) -> Self { Self { value: values[0], note_hash: values[1], diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr index df67b7f6dc28..359fae794ba8 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr @@ -4,9 +4,11 @@ use crate::{ aztec_address::AztecAddress }, constants::GENERATOR_INDEX__PARTIAL_ADDRESS, contract_class_id::ContractClassId, - hash::pedersen_hash, traits::ToField + hash::pedersen_hash, traits::{ToField, FromField, Serialize, Deserialize} }; +global PARTIAL_ADDRESS_LENGTH = 1; + // Partial address struct PartialAddress { inner : Field @@ -18,6 +20,18 @@ impl ToField for PartialAddress { } } +impl Serialize for PartialAddress { + fn serialize(self: Self) -> [Field; PARTIAL_ADDRESS_LENGTH] { + [self.to_field()] + } +} + +impl Deserialize for PartialAddress { + fn deserialize(fields: [Field; PARTIAL_ADDRESS_LENGTH]) -> Self { + PartialAddress { inner: fields[0] } + } +} + impl PartialAddress { pub fn from_field(field: Field) -> Self { Self { inner: field } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 63b35b38f275..e8e5f1cf2ee7 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -33,6 +33,8 @@ global MAX_NOTE_HASH_READ_REQUESTS_PER_CALL: u64 = 32; global MAX_NULLIFIER_READ_REQUESTS_PER_CALL: u64 = 2; // Change it to a larger value when there's a seperate reset circuit. global MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL: u64 = 2; global MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL: u64 = 1; +global MAX_ENCRYPTED_LOGS_PER_CALL: u64 = 4; // If modifying, update DEPLOYER_CONTRACT_ADDRESS. +global MAX_UNENCRYPTED_LOGS_PER_CALL: u64 = 4; // If modifying, update DEPLOYER_CONTRACT_ADDRESS. // "PER TRANSACTION" CONSTANTS global MAX_NEW_NOTE_HASHES_PER_TX: u64 = 64; @@ -46,10 +48,17 @@ global MAX_NOTE_HASH_READ_REQUESTS_PER_TX: u64 = 128; global MAX_NULLIFIER_READ_REQUESTS_PER_TX: u64 = 8; // Change it to a larger value when there's a seperate reset circuit. global MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX: u64 = 8; global MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX: u64 = 4; +global MAX_ENCRYPTED_LOGS_PER_TX: u64 = 8; +global MAX_UNENCRYPTED_LOGS_PER_TX: u64 = 8; global NUM_ENCRYPTED_LOGS_HASHES_PER_TX: u64 = 1; global NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: u64 = 1; // docs:end:constants +// KERNEL CIRCUIT PRIVATE INPUTS CONSTANTS +// global MAX_PUBLIC_DATA_HINTS: u64 = MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + MAX_PUBLIC_DATA_READS_PER_TX; +// FIX: Sadly, writing this as above causes a type error in type_conversion.ts. +global MAX_PUBLIC_DATA_HINTS: u64 = 64; + // ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts global NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP: u64 = 16; @@ -90,13 +99,12 @@ global MAX_ARGS_LENGTH: u64 = ARGS_HASH_CHUNK_COUNT * ARGS_HASH_CHUNK_LENGTH; // to be large enough so that it's ensured that it doesn't collide with storage slots of other variables. global INITIALIZATION_SLOT_SEPARATOR: Field = 1000_000_000; global INITIAL_L2_BLOCK_NUM: Field = 1; -// 126976 = 31 * 4096; -global BLOB_SIZE_IN_BYTES: Field = 126976; +global BLOB_SIZE_IN_BYTES: Field = 31 * 4096; // How much gas is subtracted from L2GASLEFT when making a nested public call by default in the AVM global NESTED_CALL_L2_GAS_BUFFER = 20000; // CONTRACT CLASS CONSTANTS -global MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS: u64 = 16000; +global MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS: u64 = 16200; // Bytecode size for private functions is per function, not for the entire contract. // Note that private functions bytecode includes a mix of acir and brillig. global MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS: u64 = 3000; @@ -118,29 +126,15 @@ global REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE = 0xe7af8166354 // CONTRACT INSTANCE CONSTANTS // sha224sum 'struct ContractInstanceDeployed' global DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE = 0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631; -global DEPLOYER_CONTRACT_ADDRESS = 0x1df42e0457430b8d294d920181cc72ae0e3c5f8afd8d62d461bd26773cfdf3c1; - -// NOIR CONSTANTS - constants used only in yarn-packages/noir-contracts -// Some are defined here because Noir doesn't yet support globals referencing other globals yet. -// Move these constants to a noir file once the issue below is resolved: -// https://github.com/noir-lang/noir/issues/1734 -global L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH: u64 = 17; -global MAX_NOTE_FIELDS_LENGTH: u64 = 20; -// GET_NOTE_ORACLE_RETURN_LENGT = MAX_NOTE_FIELDS_LENGTH + 1 + 2 -// The plus 1 is 1 extra field for nonce. -// + 2 for EXTRA_DATA: [number_of_return_notes, contract_address] -global GET_NOTE_ORACLE_RETURN_LENGTH: u64 = 23; -global MAX_NOTES_PER_PAGE: u64 = 10; -// VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * (MAX_NOTE_FIELDS_LENGTH + 1) + 2; -global VIEW_NOTE_ORACLE_RETURN_LENGTH: u64 = 212; +global DEPLOYER_CONTRACT_ADDRESS = 0x1b5ecf3d26907648cf737f4304759b8c5850478e839e72f8ce1f5791b286e8f2; // LENGTH OF STRUCTS SERIALIZED TO FIELDS global AZTEC_ADDRESS_LENGTH = 1; -global CALL_CONTEXT_LENGTH: u64 = 18; // 8 + GAS_SETTINGS_LENGTH -global GAS_SETTINGS_LENGTH: u64 = 10; // 1 + 3 * DIMENSION_GAS_SETTINGS_LENGTH global DIMENSION_GAS_SETTINGS_LENGTH: u64 = 3; global GAS_FEES_LENGTH: u64 = 3; -global GAS_USED_LENGTH: u64 = 3; +global GAS_LENGTH: u64 = 3; +global GAS_SETTINGS_LENGTH: u64 = 1 + 3 * DIMENSION_GAS_SETTINGS_LENGTH; +global CALL_CONTEXT_LENGTH: u64 = 8 + GAS_SETTINGS_LENGTH + GAS_LENGTH; global CONTENT_COMMITMENT_LENGTH: u64 = 4; global CONTRACT_INSTANCE_LENGTH: u64 = 6; global CONTRACT_STORAGE_READ_LENGTH: u64 = 2; @@ -148,26 +142,26 @@ global CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: u64 = 2; global ETH_ADDRESS_LENGTH = 1; global FUNCTION_DATA_LENGTH: u64 = 2; global FUNCTION_LEAF_PREIMAGE_LENGTH: u64 = 5; -global GLOBAL_VARIABLES_LENGTH: u64 = 9; // 6 + GAS_FEES_LENGTH -global HEADER_LENGTH: u64 = 23; // 2 for last_archive + 4 for content commitment + 8 for state reference + GLOBAL_VARIABLES_LENGTH +global GLOBAL_VARIABLES_LENGTH: u64 = 6 + GAS_FEES_LENGTH; +global APPEND_ONLY_TREE_SNAPSHOT_LENGTH = 2; global L1_TO_L2_MESSAGE_LENGTH: u64 = 6; global L2_TO_L1_MESSAGE_LENGTH: u64 = 2; global MAX_BLOCK_NUMBER_LENGTH: u64 = 2; // 1 for the option flag, 1 for the value global NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH = 4; global NULLIFIER_KEY_VALIDATION_REQUEST_CONTEXT_LENGTH = 5; global PARTIAL_STATE_REFERENCE_LENGTH: u64 = 6; -global PRIVATE_CALL_STACK_ITEM_LENGTH: u64 = 221; -// Change this ONLY if you have changed the PrivateCircuitPublicInputs structure. -// In other words, if the structure/size of the public inputs of a function call changes then we should change this -// constant as well PRIVATE_CALL_STACK_ITEM_LENGTH -global PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: u64 = 218; -// Change this ONLY if you have changed the PublicCircuitPublicInputs structure. -global PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: u64 = 209; -global STATE_REFERENCE_LENGTH: u64 = 8; // 2 for snap + 8 for partial +global READ_REQUEST_LENGTH = 2; +global SIDE_EFFECT_LENGTH = 2; +global SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH = 3; +global STATE_REFERENCE_LENGTH: u64 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; global TX_CONTEXT_DATA_LENGTH: u64 = 4; -global TX_REQUEST_LENGTH: u64 = 8; // 2 + TX_CONTEXT_DATA_LENGTH + FUNCTION_DATA_LENGTH +global TX_REQUEST_LENGTH: u64 = 2 + TX_CONTEXT_DATA_LENGTH + FUNCTION_DATA_LENGTH + GAS_SETTINGS_LENGTH; +global HEADER_LENGTH: u64 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH; +global PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: u64 = CALL_CONTEXT_LENGTH + 3 + MAX_BLOCK_NUMBER_LENGTH + (SIDE_EFFECT_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH * MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL) + (SIDE_EFFECT_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL) + (SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2 + (SIDE_EFFECT_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL) + (SIDE_EFFECT_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + 2 + HEADER_LENGTH + 2; +global PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: u64 = CALL_CONTEXT_LENGTH + 2 + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL) + (CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL) + (CONTRACT_STORAGE_READ_LENGTH * MAX_PUBLIC_DATA_READS_PER_CALL) + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + (SIDE_EFFECT_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL) + (SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2 + (SIDE_EFFECT_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + 1 + HEADER_LENGTH + AZTEC_ADDRESS_LENGTH + /* revert_code */ 1 + GAS_LENGTH; +global PRIVATE_CALL_STACK_ITEM_LENGTH: u64 = AZTEC_ADDRESS_LENGTH + FUNCTION_DATA_LENGTH + PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH; -global ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH: Field = 22; // 2 + FUNCTION_DATA_LENGTH + CALL_CONTEXT_LENGTH +global ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH: u64 = 2 + FUNCTION_DATA_LENGTH + CALL_CONTEXT_LENGTH; global GET_NOTES_ORACLE_RETURN_LENGTH: u64 = 674; global NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; global NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; @@ -178,7 +172,8 @@ global CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 52; global L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP: Field = 64; global LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64; global NUM_MSGS_PER_BASE_PARITY: u64 = 4; -// NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP / NUM_MSGS_PER_BASE_PARITY +// global NUM_BASE_PARITY_PER_ROOT_PARITY: u64 = NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP / NUM_MSGS_PER_BASE_PARITY; +// FIX: Sadly, writing this as above causes a type error in type_conversion.ts. global NUM_BASE_PARITY_PER_ROOT_PARITY: u64 = 4; /** diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_update_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_update_request.nr index 01176175f606..34654e187750 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_update_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_update_request.nr @@ -4,7 +4,7 @@ use crate::{ }; use dep::std::cmp::Eq; -struct StorageUpdateRequest{ +struct StorageUpdateRequest { storage_slot : Field, new_value : Field, } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr index 396ed601c2f3..8721314a68be 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr @@ -3,6 +3,8 @@ use crate::mocked::VerificationKey; use crate::abis::function_selector::FunctionSelector; use crate::abis::contract_class_function_leaf_preimage::ContractClassFunctionLeafPreimage; use crate::contract_class_id::ContractClassId; +use crate::abis::side_effect::SideEffect; +use crate::traits::is_empty; use crate::utils::{uint256::U256, field::field_from_bytes_32_trunc}; use crate::constants::{ FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__SILOED_NOTE_HASH, GENERATOR_INDEX__OUTER_NULLIFIER, @@ -118,13 +120,33 @@ pub fn accumulate_sha256(input: [Field; 2]) -> Field { sha256_to_field(hash_input_flattened) } -pub fn compute_logs_hash(previous_log_hash: Field, current_log_hash: Field) -> Field { - accumulate_sha256( - [ - previous_log_hash, - current_log_hash - ] - ) +pub fn compute_tx_logs_hash(logs: [SideEffect; MAX_ENCRYPTED_LOGS_PER_TX]) -> Field { + // TODO(Miranda): Below is flat hashing which would reduce constraints (we now only hash once in tail) - convert to this? + + // // Convert each field element into a byte array and append the bytes to `hash_input_flattened` + // // Ideally we would define a new global here but for now we assert in case MAX_LOGS changes + // assert(MAX_ENCRYPTED_LOGS_PER_TX * 32 == 256); + // let mut hash_input_flattened = [0; 256]; + // for offset in 0..MAX_ENCRYPTED_LOGS_PER_TX { + // let input_as_bytes = logs[offset].value.to_be_bytes(32); + // for byte_index in 0..32 { + // hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index]; + // } + // } + // // This differs from accumulate_sha256 as we could increase MAX_LOGS and + // // ideally we would push to a slice then hash, but in practice compilation was very slow + // // Hardcode to 256 bytes for now + // sha256_to_field(hash_input_flattened) + + // Assuming logs are pre-sorted + let mut accumulated_logs_hash = 0; + for i in 0..MAX_ENCRYPTED_LOGS_PER_TX { + if !is_empty(logs[i]) { + accumulated_logs_hash = accumulate_sha256([accumulated_logs_hash, logs[i].value]); + } + } + + accumulated_logs_hash } pub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: u64) -> Field { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree.nr index 67b23d3f4499..9ef29b02628f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree.nr @@ -7,8 +7,8 @@ mod root; use leaf_preimage::{IndexedTreeLeafPreimage, LeafPreimage}; use membership::{ - assert_check_membership, assert_check_non_membership, check_membership, check_non_membership, - MembershipWitness + assert_check_membership, assert_check_non_membership, check_membership, + conditionally_assert_check_membership, MembershipWitness }; use merkle_tree::MerkleTree; use root::{calculate_empty_tree_root, calculate_subtree_root, root_from_sibling_path}; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree.nr index bd8d3d1b482a..28d880c98918 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree.nr @@ -1,3 +1,5 @@ +mod check_valid_low_leaf; + use crate::{ abis::{append_only_tree_snapshot::AppendOnlyTreeSnapshot}, merkle_tree::{ diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree/check_valid_low_leaf.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree/check_valid_low_leaf.nr new file mode 100644 index 000000000000..01b4136bded0 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree/check_valid_low_leaf.nr @@ -0,0 +1,78 @@ +use crate::merkle_tree::leaf_preimage::IndexedTreeLeafPreimage; + +pub fn assert_check_valid_low_leaf( + key: Field, + low_leaf_preimage: LEAF_PREIMAGE +) where LEAF_PREIMAGE: IndexedTreeLeafPreimage { + let low_key = low_leaf_preimage.get_key(); + let next_key = low_leaf_preimage.get_next_key(); + + assert(low_key.lt(key), "Key is not greater than the low leaf"); + assert(key.lt(next_key) | (next_key == 0), "Key is not less than the next leaf"); +} + +mod tests { + use crate::{ + merkle_tree::{ + leaf_preimage::IndexedTreeLeafPreimage, + indexed_tree::check_valid_low_leaf::assert_check_valid_low_leaf + } + }; + + struct TestLeafPreimage { + value: Field, + next_value: Field, + } + + impl IndexedTreeLeafPreimage for TestLeafPreimage { + fn get_key(self) -> Field { + self.value + } + + fn get_next_key(self) -> Field { + self.next_value + } + + fn as_leaf(self) -> Field { + self.value + } + } + + #[test] + fn test_assert_check_valid_low_leaf() { + let key = 12; + let leaf = TestLeafPreimage { value: 11, next_value: 13 }; + assert_check_valid_low_leaf(key, leaf); + } + + #[test] + fn test_assert_check_empty_low_leaf() { + // An all-zero low leaf should be valid. It could be used as the first dummy leaf in a tree. + // It's not possible to prove against an empty leaf at an uninitialized index. + // The membership check will fail because the leaf value hash(0, 0) is not 0. + let key = 12; + let leaf = TestLeafPreimage { value: 0, next_value: 0 }; + assert_check_valid_low_leaf(key, leaf); + } + + #[test(should_fail_with="Key is not greater than the low leaf")] + fn test_assert_check_valid_low_leaf_failed_wrong_low_leaf() { + let key = 12; + let leaf = TestLeafPreimage { value: 13, next_value: 15 }; + assert_check_valid_low_leaf(key, leaf); + } + + #[test(should_fail_with="Key is not greater than the low leaf")] + fn test_assert_check_valid_low_leaf_failed_is_low_leaf() { + let key = 12; + let leaf = TestLeafPreimage { value: 12, next_value: 15 }; + assert_check_valid_low_leaf(key, leaf); + } + + #[test(should_fail_with="Key is not less than the next leaf")] + fn test_assert_check_valid_low_leaf_failed_wrong_next_key() { + let key = 12; + let leaf = TestLeafPreimage { value: 9, next_value: 11 }; + assert_check_valid_low_leaf(key, leaf); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/membership.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/membership.nr index d7847467dc18..d549f2699847 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/membership.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/membership.nr @@ -1,4 +1,10 @@ -use crate::{merkle_tree::{leaf_preimage::IndexedTreeLeafPreimage, root::root_from_sibling_path}, traits::Empty}; +use crate::{ + merkle_tree::{ + leaf_preimage::IndexedTreeLeafPreimage, + indexed_tree::check_valid_low_leaf::assert_check_valid_low_leaf, root::root_from_sibling_path +}, + traits::Empty +}; struct MembershipWitness { leaf_index: Field, @@ -19,36 +25,18 @@ pub fn check_membership(leaf: Field, index: Field, sibling_path: [Field; N], calculated_root == root } -pub fn assert_check_membership(leaf: Field, index: Field, sibling_path: [Field; N], root: Field) { +pub fn assert_check_membership(leaf: Field, index: Field, sibling_path: [Field; TREE_HEIGHT], root: Field) { assert(check_membership(leaf, index, sibling_path, root), "membership check failed"); } -struct NonMembershipCheckErrorCodeEnum { - NADA: u64, - IS_EMPTY: u64, - NOT_EXISTS: u64, - NOT_GREATER_THAN_LOW: u64, - NOT_LESS_THAN_NEXT: u64, -} - -global NonMembershipCheckErrorCode = NonMembershipCheckErrorCodeEnum { - NADA: 0, - IS_EMPTY: 1, - NOT_EXISTS: 2, - NOT_GREATER_THAN_LOW: 3, - NOT_LESS_THAN_NEXT: 4, -}; - -fn check_non_membership_internal( +pub fn assert_check_non_membership( key: Field, low_leaf_preimage: LEAF_PREIMAGE, low_leaf_membership_witness: MembershipWitness, tree_root: Field -) -> u64 where +) where LEAF_PREIMAGE: IndexedTreeLeafPreimage { - let low_key = low_leaf_preimage.get_key(); - let next_key = low_leaf_preimage.get_next_key(); - let is_empty_leaf = (low_key == 0) & (next_key == 0); + assert_check_valid_low_leaf(key, low_leaf_preimage); let low_leaf_exists = check_membership( low_leaf_preimage.as_leaf(), @@ -56,52 +44,31 @@ fn check_non_membership_internal( low_leaf_membership_witness.sibling_path, tree_root ); - - if is_empty_leaf { - NonMembershipCheckErrorCode.IS_EMPTY - } else if !low_leaf_exists { - NonMembershipCheckErrorCode.NOT_EXISTS - } else if !low_key.lt(key) { - NonMembershipCheckErrorCode.NOT_GREATER_THAN_LOW - } else if !key.lt(next_key) & (next_key != 0) { - NonMembershipCheckErrorCode.NOT_LESS_THAN_NEXT - } else { - NonMembershipCheckErrorCode.NADA - } + assert(low_leaf_exists, "Low leaf does not exist"); } -pub fn check_non_membership( +// Prove either membership or non-membership depending on the value of `exists`. +// If `exists` == false, `key` is not in the tree, `leaf_preimage` and `membership_witness` are for the low leaf. +pub fn conditionally_assert_check_membership( key: Field, - low_leaf_preimage: LEAF_PREIMAGE, - low_leaf_membership_witness: MembershipWitness, - tree_root: Field -) -> bool where - LEAF_PREIMAGE: IndexedTreeLeafPreimage { - let error = check_non_membership_internal(key, low_leaf_preimage, low_leaf_membership_witness, tree_root); - error == NonMembershipCheckErrorCode.NADA -} - -pub fn assert_check_non_membership( - key: Field, - low_leaf_preimage: LEAF_PREIMAGE, - low_leaf_membership_witness: MembershipWitness, + exists: bool, + leaf_preimage: LEAF_PREIMAGE, + membership_witness: MembershipWitness, tree_root: Field ) where LEAF_PREIMAGE: IndexedTreeLeafPreimage { - let error = check_non_membership_internal(key, low_leaf_preimage, low_leaf_membership_witness, tree_root); - if error != NonMembershipCheckErrorCode.NADA { - assert( - error != NonMembershipCheckErrorCode.IS_EMPTY, "Cannot check non membership against empty leaf" - ); - assert(error != NonMembershipCheckErrorCode.NOT_EXISTS, "Low leaf does not exist"); - assert( - error != NonMembershipCheckErrorCode.NOT_GREATER_THAN_LOW, "Key is not greater than the low leaf" - ); - assert( - error != NonMembershipCheckErrorCode.NOT_LESS_THAN_NEXT, "Key is not less than the next leaf" - ); - assert(false, "Unknown error"); + if exists { + assert(key == leaf_preimage.get_key(), "Key does not match the key of the leaf preimage"); + } else { + assert_check_valid_low_leaf(key, leaf_preimage); } + + assert_check_membership( + leaf_preimage.as_leaf(), + membership_witness.leaf_index, + membership_witness.sibling_path, + tree_root + ); } mod tests { @@ -109,8 +76,8 @@ mod tests { merkle_tree::{ leaf_preimage::{IndexedTreeLeafPreimage, LeafPreimage}, membership::{ - assert_check_membership, assert_check_non_membership, check_membership, check_non_membership, - MembershipWitness + assert_check_membership, assert_check_non_membership, check_membership, + conditionally_assert_check_membership, MembershipWitness } }, tests::merkle_tree_utils::NonEmptyMerkleTree @@ -186,7 +153,7 @@ mod tests { ); } - fn check_non_membership_at_index(low_leaf_index: u64, leaf: Field) -> bool { + fn assert_check_non_membership_at_index(low_leaf_index: u64, key: Field) { let tree = build_tree(); let tree_root = tree.get_root(); let leaf_preimage = if low_leaf_index < leaf_preimages.len() { @@ -195,15 +162,15 @@ mod tests { TestLeafPreimage { value: 0, next_value: 0 } }; - check_non_membership( - leaf, + assert_check_non_membership( + key, leaf_preimage, MembershipWitness { leaf_index: low_leaf_index as Field, sibling_path: tree.get_sibling_path(low_leaf_index) } , tree_root - ) + ); } - fn assert_check_non_membership_at_index(low_leaf_index: u64, leaf: Field) { + fn conditionally_assert_check_membership_at_index(exists: bool, low_leaf_index: u64, key: Field) { let tree = build_tree(); let tree_root = tree.get_root(); let leaf_preimage = if low_leaf_index < leaf_preimages.len() { @@ -212,8 +179,9 @@ mod tests { TestLeafPreimage { value: 0, next_value: 0 } }; - assert_check_non_membership( - leaf, + conditionally_assert_check_membership( + key, + exists, leaf_preimage, MembershipWitness { leaf_index: low_leaf_index as Field, sibling_path: tree.get_sibling_path(low_leaf_index) } , tree_root @@ -270,80 +238,89 @@ mod tests { ); } - #[test] - fn test_check_non_membership() { - assert_eq(check_non_membership_at_index(0, 25), true); - } - #[test] fn test_assert_check_non_membership() { assert_check_non_membership_at_index(0, 25); } - #[test] - fn test_check_non_membership_greater_than_max() { - assert_eq(check_non_membership_at_index(1, 45), true); - } - #[test] fn test_assert_check_non_membership_greater_than_max() { assert_check_non_membership_at_index(1, 45); } - #[test] - fn test_check_non_membership_false_empty_leaf() { - assert_eq(check_non_membership_at_index(4, 25), false); + #[test(should_fail_with="Key is not greater than the low leaf")] + fn test_assert_check_non_membership_failed_wrong_low_leaf() { + assert_check_non_membership_at_index(3, 25); } - #[test(should_fail_with="Cannot check non membership against empty leaf")] - fn test_assert_check_non_membership_failed_empty_leaf() { - assert_check_non_membership_at_index(4, 25); + #[test(should_fail_with="Key is not less than the next leaf")] + fn test_assert_check_non_membership_failed_wrong_next_key() { + assert_check_non_membership_at_index(2, 25); } - #[test] - fn test_check_non_membership_false_wrong_low_leaf() { - assert_eq(check_non_membership_at_index(3, 25), false); + #[test(should_fail_with="Low leaf does not exist")] + fn test_assert_check_non_membership_failed_invalid_leaf() { + let tree = build_tree(); + let tree_root = tree.get_root(); + + let fake_leaf = TestLeafPreimage { value: 50, next_value: 60 }; + assert_check_non_membership( + 55, + fake_leaf, + MembershipWitness { leaf_index: 1, sibling_path: tree.get_sibling_path(1) } , + tree_root + ); } - #[test(should_fail_with="Key is not greater than the low leaf")] - fn test_assert_check_non_membership_failed_wrong_low_leaf() { - assert_check_non_membership_at_index(3, 25); + #[test] + fn test_conditionally_assert_check_membership_exists() { + conditionally_assert_check_membership_at_index(true, 1, leaf_preimages[1].get_key()); } #[test] - fn test_check_non_membership_false_wrong_next_key() { - assert_eq(check_non_membership_at_index(2, 25), false); + fn test_conditionally_assert_check_membership_not_exists() { + conditionally_assert_check_membership_at_index(false, 1, leaf_preimages[1].get_key() + 1); + } + + #[test(should_fail_with="Key does not match the key of the leaf preimage")] + fn test_conditionally_assert_check_membership_exists_value_mismatch() { + conditionally_assert_check_membership_at_index(true, 1, leaf_preimages[1].get_key() + 1); + } + + #[test(should_fail_with="Key is not greater than the low leaf")] + fn test_conditionally_assert_check_membership_failed_not_exists_wrong_low_leaf() { + conditionally_assert_check_membership_at_index(false, 3, 25); } #[test(should_fail_with="Key is not less than the next leaf")] - fn test_assert_check_non_membership_failed_wrong_next_key() { - assert_check_non_membership_at_index(2, 25); + fn test_conditionally_assert_check_membership_failed_not_exists_wrong_next_key() { + conditionally_assert_check_membership_at_index(false, 2, 25); } - #[test] - fn test_check_non_membership_false_invalid_leaf() { + #[test(should_fail_with="membership check failed")] + fn test_conditionally_assert_check_membership_failed_exists_invalid_leaf() { let tree = build_tree(); let tree_root = tree.get_root(); - let fake_leaf = TestLeafPreimage { value: 50, next_value: 60 }; - assert_eq( - check_non_membership( - 55, - fake_leaf, - MembershipWitness { leaf_index: 1, sibling_path: tree.get_sibling_path(1) } , - tree_root - ), false + let exists = true; + conditionally_assert_check_membership( + 50, + exists, + fake_leaf, + MembershipWitness { leaf_index: 1, sibling_path: tree.get_sibling_path(1) } , + tree_root ); } - #[test(should_fail_with="Low leaf does not exist")] - fn test_assert_check_non_membership_failed_invalid_leaf() { + #[test(should_fail_with="membership check failed")] + fn test_conditionally_assert_check_membership_failed_not_exists_invalid_leaf() { let tree = build_tree(); let tree_root = tree.get_root(); - let fake_leaf = TestLeafPreimage { value: 50, next_value: 60 }; - assert_check_non_membership( + let exists = false; + conditionally_assert_check_membership( 55, + exists, fake_leaf, MembershipWitness { leaf_index: 1, sibling_path: tree.get_sibling_path(1) } , tree_root diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/public_data_tree_leaf_preimage.nr b/noir-projects/noir-protocol-circuits/crates/types/src/public_data_tree_leaf_preimage.nr index dcc84fe7026b..992bbdecd180 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/public_data_tree_leaf_preimage.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/public_data_tree_leaf_preimage.nr @@ -1,4 +1,4 @@ -use crate::traits::{Empty, Hash}; +use crate::{merkle_tree::leaf_preimage::IndexedTreeLeafPreimage, traits::{Empty, Hash}}; struct PublicDataTreeLeafPreimage { slot : Field, @@ -28,6 +28,20 @@ impl Hash for PublicDataTreeLeafPreimage { } } +impl IndexedTreeLeafPreimage for PublicDataTreeLeafPreimage { + fn get_key(self) -> Field { + self.slot + } + + fn get_next_key(self) -> Field { + self.next_slot + } + + fn as_leaf(self) -> Field { + self.hash() + } +} + impl PublicDataTreeLeafPreimage { pub fn is_empty(self) -> bool { (self.slot == 0) & (self.value == 0) & (self.next_slot == 0) & (self.next_index == 0) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index bf56794334de..d0e548613710 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -1,6 +1,6 @@ use crate::{ abis::{ - gas_used::GasUsed, gas_settings::GasSettings, call_context::CallContext, + gas::Gas, gas_settings::GasSettings, call_context::CallContext, call_request::{CallerContext, CallRequest}, accumulated_data::{ CombinedAccumulatedData, PrivateAccumulatedData, PrivateAccumulatedDataBuilder, @@ -21,10 +21,11 @@ use crate::{ MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, - VK_TREE_HEIGHT + VK_TREE_HEIGHT, MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX }, hash::silo_nullifier, header::Header, mocked::{AggregationObject, Proof, VerificationKey}, - tests::fixtures, transaction::tx_context::TxContext, traits::Empty + partial_state_reference::PartialStateReference, tests::fixtures, transaction::tx_context::TxContext, + traits::Empty }; struct FixtureBuilder { @@ -40,6 +41,8 @@ struct FixtureBuilder { new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, new_l2_to_l1_msgs: BoundedVec, + encrypted_logs_hashes: BoundedVec, + unencrypted_logs_hashes: BoundedVec, encrypted_logs_hash: Field, unencrypted_logs_hash: Field, encrypted_log_preimages_length: Field, @@ -47,7 +50,7 @@ struct FixtureBuilder { public_data_update_requests: BoundedVec, private_call_stack: BoundedVec, public_call_stack: BoundedVec, - gas_used: GasUsed, + gas_used: Gas, // Validation requests. max_block_number: MaxBlockNumber, @@ -67,6 +70,9 @@ struct FixtureBuilder { // Counters. min_revertible_side_effect_counter: u32, counter: u32, + + // States. + start_state: PartialStateReference, } impl FixtureBuilder { @@ -81,6 +87,8 @@ impl FixtureBuilder { new_note_hashes: BoundedVec::new(), new_nullifiers: BoundedVec::new(), new_l2_to_l1_msgs: BoundedVec::new(), + encrypted_logs_hashes: BoundedVec::new(), + unencrypted_logs_hashes: BoundedVec::new(), encrypted_logs_hash: 0, unencrypted_logs_hash: 0, encrypted_log_preimages_length: 0, @@ -101,7 +109,8 @@ impl FixtureBuilder { revert_code: 0, min_revertible_side_effect_counter: 0, counter: 0, - gas_used: GasUsed::empty(), + start_state: PartialStateReference::empty(), + gas_used: Gas::empty(), gas_settings: GasSettings::empty() } } @@ -119,8 +128,8 @@ impl FixtureBuilder { new_note_hashes: self.new_note_hashes, new_nullifiers: self.new_nullifiers, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_logs_hashes: self.encrypted_logs_hashes, + unencrypted_logs_hashes: self.unencrypted_logs_hashes, encrypted_log_preimages_length: self.encrypted_log_preimages_length, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, private_call_stack: self.private_call_stack, @@ -135,8 +144,8 @@ impl FixtureBuilder { new_note_hashes: self.new_note_hashes, new_nullifiers: self.new_nullifiers, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_logs_hashes: self.encrypted_logs_hashes, + unencrypted_logs_hashes: self.unencrypted_logs_hashes, encrypted_log_preimages_length: self.encrypted_log_preimages_length, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, public_data_update_requests: self.public_data_update_requests, @@ -231,6 +240,7 @@ impl FixtureBuilder { rollup_validation_requests, end, constants, + start_state: self.start_state, revert_code: self.revert_code } } @@ -267,17 +277,21 @@ impl FixtureBuilder { } } + pub fn add_public_data_update_request(&mut self, leaf_slot: Field, value: Field) { + let update_request = PublicDataUpdateRequest { leaf_slot, new_value: value }; + self.public_data_update_requests.push(update_request); + } + pub fn append_public_data_update_requests(&mut self, num_updates: u64) { let value_offset = self.public_data_update_requests.len(); for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { if i < num_updates { - let update_request = PublicDataUpdateRequest { - // The default leaf index is its index + 23. - leaf_slot: (value_offset + i + 23) as Field, - // The default value is its index + 678. - new_value: (value_offset + i + 678) as Field - }; - self.public_data_update_requests.push(update_request); + // The default leaf index is its index + 23. + // The default value is its index + 678. + self.add_public_data_update_request( + (value_offset + i + 23) as Field, + (value_offset + i + 678) as Field + ); } } } @@ -326,12 +340,32 @@ impl FixtureBuilder { self.nullifier_non_existent_read_requests.push(read_request); } + pub fn add_read_request_for_pending_public_data(&mut self, public_date_update_request_index: u64) -> u64 { + let new_read_request_index = self.public_data_reads.len(); + let public_write = self.public_data_update_requests.get(public_date_update_request_index); + let read_request = PublicDataRead { leaf_slot: public_write.leaf_slot, value: public_write.new_value }; + self.public_data_reads.push(read_request); + new_read_request_index + } + pub fn set_encrypted_logs(&mut self, hash: Field, preimages_length: Field) { + let side_effect = SideEffect { value: hash, counter: self.next_counter() }; + self.encrypted_logs_hashes.push(side_effect); + self.encrypted_log_preimages_length += preimages_length; + } + + pub fn set_unencrypted_logs(&mut self, hash: Field, preimages_length: Field) { + let side_effect = SideEffect { value: hash, counter: self.next_counter() }; + self.unencrypted_logs_hashes.push(side_effect); + self.unencrypted_log_preimages_length += preimages_length; + } + + pub fn set_encrypted_logs_hash(&mut self, hash: Field, preimages_length: Field) { self.encrypted_logs_hash = hash; self.encrypted_log_preimages_length = preimages_length; } - pub fn set_unencrypted_logs(&mut self, hash: Field, preimages_length: Field) { + pub fn set_unencrypted_logs_hash(&mut self, hash: Field, preimages_length: Field) { self.unencrypted_logs_hash = hash; self.unencrypted_log_preimages_length = preimages_length; } @@ -399,6 +433,8 @@ impl Empty for FixtureBuilder { new_note_hashes: BoundedVec::new(), new_nullifiers: BoundedVec::new(), new_l2_to_l1_msgs: BoundedVec::new(), + encrypted_logs_hashes: BoundedVec::new(), + unencrypted_logs_hashes: BoundedVec::new(), encrypted_logs_hash: 0, unencrypted_logs_hash: 0, encrypted_log_preimages_length: 0, @@ -419,8 +455,9 @@ impl Empty for FixtureBuilder { revert_code: 0, min_revertible_side_effect_counter: 0, counter: 0, + start_state: PartialStateReference::empty(), gas_settings: GasSettings::empty(), - gas_used: GasUsed::empty(), + gas_used: Gas::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr index 7ed7b0de8187..bceb7f0fbba5 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_call_data_builder.nr @@ -1,10 +1,11 @@ use crate::{ abis::{ - call_request::{CallerContext, CallRequest}, private_call_stack_item::PrivateCallStackItem, - function_data::FunctionData, max_block_number::MaxBlockNumber, + gas_settings::GasSettings, call_request::{CallerContext, CallRequest}, + private_call_stack_item::PrivateCallStackItem, function_data::FunctionData, + max_block_number::MaxBlockNumber, membership_witness::{FunctionLeafMembershipWitness, NoteHashReadRequestMembershipWitness}, - private_circuit_public_inputs::PrivateCircuitPublicInputs, - private_kernel::private_call_data::PrivateCallData + private_circuit_public_inputs::{PrivateCircuitPublicInputs}, + private_kernel::private_call_data::PrivateCallData, side_effect::SideEffect, }, address::{AztecAddress, EthAddress, SaltedInitializationHash, PublicKeysHash}, mocked::{Proof, VerificationKey}, @@ -38,6 +39,7 @@ struct PrivateCallDataBuilder { note_hash_read_request_membership_witnesses: BoundedVec, portal_contract_address: EthAddress, acir_hash: Field, + gas_settings: GasSettings, } impl PrivateCallDataBuilder { @@ -64,7 +66,8 @@ impl PrivateCallDataBuilder { contract_class_public_bytecode_commitment: contract_data.public_bytecode_commitment, note_hash_read_request_membership_witnesses: BoundedVec::new(), portal_contract_address: public_inputs.call_context.portal_contract_address, - acir_hash: contract_function.acir_hash + acir_hash: contract_function.acir_hash, + gas_settings: public_inputs.call_context.gas_settings } } @@ -87,7 +90,8 @@ impl PrivateCallDataBuilder { origin: self.contract_address, args_hash: self.public_inputs.args_hash, tx_context, - function_data: self.function_data + function_data: self.function_data, + gas_settings: self.gas_settings } } @@ -156,13 +160,17 @@ impl PrivateCallDataBuilder { } pub fn set_encrypted_logs(&mut self, hash: Field, preimages_length: Field) { - self.public_inputs.encrypted_logs_hash = hash; - self.public_inputs.encrypted_log_preimages_length = preimages_length; + // Counter set as 0 for testing, like note read requests + let side_effect = SideEffect { value: hash, counter: 0 }; + self.public_inputs.encrypted_logs_hashes.push(side_effect); + self.public_inputs.encrypted_log_preimages_length += preimages_length; } pub fn set_unencrypted_logs(&mut self, hash: Field, preimages_length: Field) { - self.public_inputs.unencrypted_logs_hash = hash; - self.public_inputs.unencrypted_log_preimages_length = preimages_length; + // Counter set as 0 for testing, like note read requests + let side_effect = SideEffect { value: hash, counter: 0 }; + self.public_inputs.unencrypted_logs_hashes.push(side_effect); + self.public_inputs.unencrypted_log_preimages_length += preimages_length; } pub fn get_call_stack_item_hash(self) -> Field { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_circuit_public_inputs_builder.nr index 56d4175f62cf..e72d8ee686ea 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/private_circuit_public_inputs_builder.nr @@ -1,6 +1,6 @@ use crate::{ abis::{ - call_context::CallContext, gas_settings::{GasSettings, DimensionGasSettings}, + call_context::CallContext, gas_settings::{GasSettings, DimensionGasSettings}, gas::Gas, max_block_number::MaxBlockNumber, nullifier_key_validation_request::NullifierKeyValidationRequest, private_circuit_public_inputs::PrivateCircuitPublicInputs, read_request::ReadRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash} @@ -13,7 +13,8 @@ use crate::{ MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_ENCRYPTED_LOGS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL }, traits::Empty }; @@ -39,8 +40,8 @@ struct PrivateCircuitPublicInputsBuilder { public_call_stack_hashes: BoundedVec, new_l2_to_l1_msgs: BoundedVec, - encrypted_logs_hash: Field, - unencrypted_logs_hash: Field, + encrypted_logs_hashes: BoundedVec, + unencrypted_logs_hashes: BoundedVec, encrypted_log_preimages_length: Field, unencrypted_log_preimages_length: Field, @@ -73,12 +74,8 @@ impl PrivateCircuitPublicInputsBuilder { is_delegate_call: false, is_static_call: false, side_effect_counter: 0, - gas_settings: GasSettings { - da: DimensionGasSettings::new(0, 0, 0), - l1: DimensionGasSettings::new(0, 0, 0), - l2: DimensionGasSettings::new(0, 0, 0), - inclusion_fee: 0 - }, + gas_left: Gas::empty(), + gas_settings: GasSettings::empty(), transaction_fee: 0 }; public_inputs.call_context = call_context; @@ -107,8 +104,8 @@ impl PrivateCircuitPublicInputsBuilder { new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, start_side_effect_counter: self.call_context.side_effect_counter, end_side_effect_counter: 10, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_logs_hashes: self.encrypted_logs_hashes.storage, + unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, encrypted_log_preimages_length: self.encrypted_log_preimages_length, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, historical_header: self.historical_header, @@ -134,8 +131,8 @@ impl Empty for PrivateCircuitPublicInputsBuilder { private_call_stack_hashes: BoundedVec::new(), public_call_stack_hashes: BoundedVec::new(), new_l2_to_l1_msgs: BoundedVec::new(), - encrypted_logs_hash: 0, - unencrypted_logs_hash: 0, + encrypted_logs_hashes: BoundedVec::new(), + unencrypted_logs_hashes: BoundedVec::new(), encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, historical_header: Header::empty(), @@ -143,4 +140,4 @@ impl Empty for PrivateCircuitPublicInputsBuilder { version: 0, } } -} \ No newline at end of file +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/public_call_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/public_call_data_builder.nr index 7338a7263635..262a2dd4c546 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/public_call_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/public_call_data_builder.nr @@ -1,8 +1,9 @@ use crate::{ abis::{ - gas_settings::GasSettings, call_context::CallContext, call_request::{CallerContext, CallRequest}, - function_data::FunctionData, public_call_data::PublicCallData, - public_call_stack_item::PublicCallStackItem, public_circuit_public_inputs::PublicCircuitPublicInputs + gas_settings::GasSettings, gas::Gas, call_context::CallContext, + call_request::{CallerContext, CallRequest}, function_data::FunctionData, + public_call_data::PublicCallData, public_call_stack_item::PublicCallStackItem, + public_circuit_public_inputs::PublicCircuitPublicInputs, side_effect::SideEffect }, address::{AztecAddress, EthAddress}, contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, mocked::Proof, @@ -45,6 +46,7 @@ impl PublicCallDataBuilder { side_effect_counter: 0, // needed? gas_settings: GasSettings::empty(), transaction_fee: 0, + gas_left: Gas::empty(), }; PublicCallDataBuilder { @@ -150,8 +152,10 @@ impl PublicCallDataBuilder { } pub fn set_unencrypted_logs(&mut self, hash: Field, preimages_length: Field) { - self.public_inputs.unencrypted_logs_hash = hash; - self.public_inputs.unencrypted_log_preimages_length = preimages_length; + // Counter set as 0 for testing, like note read requests + let side_effect = SideEffect { value: hash, counter: 0 }; + self.public_inputs.unencrypted_logs_hashes.push(side_effect); + self.public_inputs.unencrypted_log_preimages_length += preimages_length; } pub fn finish(self) -> PublicCallData { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/public_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/public_circuit_public_inputs_builder.nr index 2898875fce68..6556b96d8acc 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/public_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/public_circuit_public_inputs_builder.nr @@ -1,6 +1,6 @@ use crate::{ abis::{ - call_context::CallContext, public_circuit_public_inputs::PublicCircuitPublicInputs, + gas::Gas, call_context::CallContext, public_circuit_public_inputs::PublicCircuitPublicInputs, read_request::ReadRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, address::AztecAddress, @@ -12,9 +12,9 @@ use crate::{ MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL }, -traits::Empty, + traits::Empty }; struct PublicCircuitPublicInputsBuilder { @@ -31,11 +31,12 @@ struct PublicCircuitPublicInputsBuilder { new_l2_to_l1_msgs: BoundedVec, start_side_effect_counter: u32, end_side_effect_counter: u32, - unencrypted_logs_hash: Field, + unencrypted_logs_hashes: BoundedVec, unencrypted_log_preimages_length: Field, historical_header: Header, prover_address: AztecAddress, revert_code: u8, + gas_left: Gas, } impl PublicCircuitPublicInputsBuilder { @@ -61,11 +62,12 @@ impl PublicCircuitPublicInputsBuilder { new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, start_side_effect_counter: self.start_side_effect_counter, end_side_effect_counter: self.end_side_effect_counter, - unencrypted_logs_hash: self.unencrypted_logs_hash, + unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, historical_header: self.historical_header, prover_address: self.prover_address, - revert_code: self.revert_code + revert_code: self.revert_code, + gas_left: self.gas_left } } } @@ -86,11 +88,12 @@ impl Empty for PublicCircuitPublicInputsBuilder { new_l2_to_l1_msgs: BoundedVec::new(), start_side_effect_counter: 0 as u32, end_side_effect_counter: 0 as u32, - unencrypted_logs_hash: 0, + unencrypted_logs_hashes: BoundedVec::new(), unencrypted_log_preimages_length: 0, historical_header: Header::empty(), prover_address: AztecAddress::zero(), revert_code: 0 as u8, + gas_left: Gas::empty(), } } -} \ No newline at end of file +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr b/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr index 70870f64d849..4d272c90cbae 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr @@ -1,4 +1,5 @@ use dep::std::cmp::Eq; +use crate::utils::field::field_from_bytes; // Trait: is_empty // @@ -55,6 +56,12 @@ impl ToField for U128 { self.to_integer() } } +impl ToField for str { + fn to_field(self) -> Field { + assert(N < 32, "String doesn't fit in a field, consider using Serialize instead"); + field_from_bytes(self.as_bytes(), true) + } +} trait FromField { fn from_field(value: Field) -> Self; @@ -83,6 +90,17 @@ trait Serialize { } // docs:end:serialize +impl Serialize for str { + fn serialize(self) -> [Field; N] { + let mut result = [0; N]; + let bytes: [u8; N] = self.as_bytes(); + for i in 0..N { + result[i] = field_from_bytes([bytes[i];1], true); + } + result + } +} + // docs:start:deserialize trait Deserialize { fn deserialize(fields: [Field; N]) -> Self; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr index 74be0805af57..59b1299d7e06 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr @@ -1,7 +1,8 @@ use crate::{ - address::AztecAddress, abis::function_data::FunctionData, + address::AztecAddress, abis::function_data::FunctionData, abis::gas_settings::GasSettings, constants::{GENERATOR_INDEX__TX_REQUEST, TX_REQUEST_LENGTH}, hash::pedersen_hash, - traits::{Hash, Serialize, Deserialize, Empty}, transaction::tx_context::TxContext, utils::reader::Reader + traits::{Hash, Serialize, Deserialize, Empty}, transaction::tx_context::TxContext, + utils::reader::Reader }; struct TxRequest { @@ -9,6 +10,7 @@ struct TxRequest { args_hash: Field, tx_context: TxContext, function_data: FunctionData, + gas_settings: GasSettings, } impl Empty for TxRequest { @@ -17,7 +19,8 @@ impl Empty for TxRequest { origin: AztecAddress::empty(), args_hash: 0, tx_context: TxContext::empty(), - function_data: FunctionData::empty() + function_data: FunctionData::empty(), + gas_settings: GasSettings::empty(), } } } @@ -27,7 +30,8 @@ impl Eq for TxRequest { (self.origin == other.origin) & (self.args_hash == other.args_hash) & (self.tx_context == other.tx_context) & - (self.function_data == other.function_data) + (self.function_data == other.function_data) & + (self.gas_settings == other.gas_settings) } } @@ -46,6 +50,7 @@ impl Serialize for TxRequest { fields.extend_from_array(self.function_data.serialize()); fields.push(self.args_hash); fields.extend_from_array(self.tx_context.serialize()); + fields.extend_from_array(self.gas_settings.serialize()); assert_eq(fields.len(), TX_REQUEST_LENGTH); @@ -62,6 +67,7 @@ impl Deserialize for TxRequest { args_hash: reader.read(), tx_context: reader.read_struct(TxContext::deserialize), function_data: reader.read_struct(FunctionData::deserialize), + gas_settings: reader.read_struct(GasSettings::deserialize), }; reader.finish(); @@ -71,7 +77,10 @@ impl Deserialize for TxRequest { mod tests { use crate::{ - abis::{function_selector::FunctionSelector, function_data::FunctionData}, + abis::{ + function_selector::FunctionSelector, function_data::FunctionData, + gas_settings::{GasSettings, DimensionGasSettings} + }, address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId, grumpkin_point::GrumpkinPoint, transaction::{tx_request::TxRequest, tx_context::TxContext} }; @@ -90,10 +99,16 @@ mod tests { origin: AztecAddress::from_field(1), args_hash: 3, tx_context: TxContext { is_fee_payment_tx: false, is_rebate_payment_tx: false, chain_id: 0, version: 0 }, - function_data: FunctionData { selector: FunctionSelector::from_u32(2), is_private: true } + function_data: FunctionData { selector: FunctionSelector::from_u32(2), is_private: true }, + gas_settings: GasSettings { + da: DimensionGasSettings { gas_limit: 2, teardown_gas_limit: 1, max_fee_per_gas: 3 }, + l1: DimensionGasSettings { gas_limit: 2, teardown_gas_limit: 1, max_fee_per_gas: 3 }, + l2: DimensionGasSettings { gas_limit: 2, teardown_gas_limit: 1, max_fee_per_gas: 3 }, + inclusion_fee: 10 + } }; // Value from tx_request.test.ts "compute hash" test - let test_data_tx_request_hash = 0x20af6f595c396494f1177fa196d17e98d55a2416b28c262b76e78a36d6c01daa; + let test_data_tx_request_hash = 0x03b678e327818eb368f9eac21839ee67a98968318f0dcd76c89d3fcf66af7257; assert(tx_request.hash() == test_data_tx_request_hash); } } diff --git a/noir/Earthfile b/noir/Earthfile index 099db3102f21..9e1f7610b82b 100644 --- a/noir/Earthfile +++ b/noir/Earthfile @@ -26,13 +26,14 @@ nargo: SAVE IMAGE aztecprotocol/nargo packages: + BUILD ../barretenberg/ts/+build # prefetch FROM node:20 RUN curl https://sh.rustup.rs -sSf | bash -s -- -y RUN echo 'source $HOME/.cargo/env' >> $HOME/.bashrc RUN apt update && apt install -y jq libc++1 - # `noir-repo` is nested inside of `noir` so we copy `bb.js` as such to account + # `noir-repo` is nested inside of `noir` so we copy `bb.js` as such to account # for the extra nested folder specified in portalled package paths COPY ../barretenberg/ts/+build/build /usr/src/../barretenberg/ts @@ -105,8 +106,8 @@ build: # FROM scratch # COPY --from=builder /usr/src/noir/README.md /usr/src/noir/README.md -# TODO -# test: +# TODO +# test: # FROM rust:bullseye # ARG COMMIT_HASH # ENV COMMIT_HASH=${COMMIT_HASH} diff --git a/noir/noir-repo/.github/workflows/test-rust-workspace-msrv.yml b/noir/noir-repo/.github/workflows/test-rust-workspace-msrv.yml index 0b2855fa8349..cdd7a064a8d4 100644 --- a/noir/noir-repo/.github/workflows/test-rust-workspace-msrv.yml +++ b/noir/noir-repo/.github/workflows/test-rust-workspace-msrv.yml @@ -112,6 +112,10 @@ jobs: # We treat any cancelled, skipped or failing jobs as a failure for the workflow as a whole. FAIL: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }} + - name: Checkout + if: ${{ failure() }} + uses: actions/checkout@v4 + # Raise an issue if the tests failed - name: Alert on failed publish uses: JasonEtco/create-an-issue@v2 @@ -122,4 +126,4 @@ jobs: WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} with: update_existing: true - filename: .github/JS_PUBLISH_FAILED.md \ No newline at end of file + filename: .github/ACVM_NOT_PUBLISHABLE.md diff --git a/noir/noir-repo/.gitignore b/noir/noir-repo/.gitignore index 9a829afab8b6..2c877a4d02c4 100644 --- a/noir/noir-repo/.gitignore +++ b/noir/noir-repo/.gitignore @@ -4,6 +4,7 @@ examples/**/target/ examples/9 node_modules pkg/ +.idea # Yarn .pnp.* diff --git a/noir/noir-repo/Cargo.lock b/noir/noir-repo/Cargo.lock index e62f966b8fd5..ee83f7f8ddf3 100644 --- a/noir/noir-repo/Cargo.lock +++ b/noir/noir-repo/Cargo.lock @@ -13,6 +13,7 @@ dependencies = [ "flate2", "fxhash", "serde", + "serde-big-array", "serde-generate", "serde-reflection", "serde_json", @@ -60,6 +61,7 @@ dependencies = [ "blake3", "k256", "keccak", + "num-bigint", "p256", "sha2", "sha3", @@ -268,7 +270,7 @@ dependencies = [ "ark-std", "derivative", "hashbrown 0.13.2", - "itertools", + "itertools 0.10.5", "num-traits", "zeroize", ] @@ -285,7 +287,7 @@ dependencies = [ "ark-std", "derivative", "digest", - "itertools", + "itertools 0.10.5", "num-bigint", "num-traits", "paste", @@ -374,6 +376,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + [[package]] name = "assert_cmd" version = "2.0.12" @@ -606,11 +617,14 @@ dependencies = [ "ark-ec", "ark-ff", "cfg-if 1.0.0", + "criterion", "getrandom 0.2.10", + "hex", "js-sys", + "lazy_static", "noir_grumpkin", "num-bigint", - "num-traits", + "pprof", "thiserror", "wasm-bindgen-futures", "wasmer", @@ -1178,7 +1192,7 @@ dependencies = [ "clap", "criterion-plot", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -1199,7 +1213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -1255,6 +1269,12 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-bigint" version = "0.4.9" @@ -1526,6 +1546,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ena" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +dependencies = [ + "log", +] + [[package]] name = "encode_unicode" version = "0.3.6" @@ -2364,6 +2393,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -2534,6 +2572,37 @@ dependencies = [ "libc", ] +[[package]] +name = "lalrpop" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools 0.11.0", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax 0.8.2", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata 0.4.5", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -2856,6 +2925,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nibble_vec" version = "0.1.0" @@ -3087,6 +3162,8 @@ dependencies = [ "chumsky", "fm", "iter-extended", + "lalrpop", + "lalrpop-util", "noirc_errors", "noirc_printable_type", "petgraph", @@ -3386,6 +3463,12 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -3470,6 +3553,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "predicates" version = "2.1.5" @@ -3478,7 +3567,7 @@ checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "float-cmp", - "itertools", + "itertools 0.10.5", "normalize-line-endings", "predicates-core", "regex", @@ -3492,7 +3581,7 @@ checksum = "09963355b9f467184c04017ced4a2ba2d75cbcb4e7462690d388233253d4b1a9" dependencies = [ "anstyle", "difflib", - "itertools", + "itertools 0.10.5", "predicates-core", ] @@ -4297,6 +4386,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + [[package]] name = "serde-generate" version = "0.25.1" @@ -4603,6 +4701,19 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot 0.12.1", + "phf_shared", + "precomputed-hash", +] + [[package]] name = "strsim" version = "0.10.0" @@ -4845,6 +4956,15 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -5266,9 +5386,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.3" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", diff --git a/noir/noir-repo/acvm-repo/acir/Cargo.toml b/noir/noir-repo/acvm-repo/acir/Cargo.toml index 99095ad3f613..4fae9ea20ff9 100644 --- a/noir/noir-repo/acvm-repo/acir/Cargo.toml +++ b/noir/noir-repo/acvm-repo/acir/Cargo.toml @@ -20,6 +20,7 @@ thiserror.workspace = true flate2.workspace = true bincode.workspace = true base64.workspace = true +serde-big-array = "0.5.1" [dev-dependencies] serde_json = "1.0" diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index 7cd9fbefba09..6c7bd347e5d0 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -54,7 +54,7 @@ namespace Program { struct SHA256 { std::vector inputs; - std::vector outputs; + std::array outputs; friend bool operator==(const SHA256&, const SHA256&); std::vector bincodeSerialize() const; @@ -63,7 +63,7 @@ namespace Program { struct Blake2s { std::vector inputs; - std::vector outputs; + std::array outputs; friend bool operator==(const Blake2s&, const Blake2s&); std::vector bincodeSerialize() const; @@ -72,7 +72,7 @@ namespace Program { struct Blake3 { std::vector inputs; - std::vector outputs; + std::array outputs; friend bool operator==(const Blake3&, const Blake3&); std::vector bincodeSerialize() const; @@ -82,7 +82,7 @@ namespace Program { struct SchnorrVerify { Program::FunctionInput public_key_x; Program::FunctionInput public_key_y; - std::vector signature; + std::array signature; std::vector message; Program::Witness output; @@ -112,10 +112,10 @@ namespace Program { }; struct EcdsaSecp256k1 { - std::vector public_key_x; - std::vector public_key_y; - std::vector signature; - std::vector hashed_message; + std::array public_key_x; + std::array public_key_y; + std::array signature; + std::array hashed_message; Program::Witness output; friend bool operator==(const EcdsaSecp256k1&, const EcdsaSecp256k1&); @@ -124,10 +124,10 @@ namespace Program { }; struct EcdsaSecp256r1 { - std::vector public_key_x; - std::vector public_key_y; - std::vector signature; - std::vector hashed_message; + std::array public_key_x; + std::array public_key_y; + std::array signature; + std::array hashed_message; Program::Witness output; friend bool operator==(const EcdsaSecp256r1&, const EcdsaSecp256r1&); @@ -160,7 +160,7 @@ namespace Program { struct Keccak256 { std::vector inputs; Program::FunctionInput var_message_size; - std::vector outputs; + std::array outputs; friend bool operator==(const Keccak256&, const Keccak256&); std::vector bincodeSerialize() const; @@ -168,8 +168,8 @@ namespace Program { }; struct Keccakf1600 { - std::vector inputs; - std::vector outputs; + std::array inputs; + std::array outputs; friend bool operator==(const Keccakf1600&, const Keccakf1600&); std::vector bincodeSerialize() const; @@ -257,9 +257,9 @@ namespace Program { }; struct Sha256Compression { - std::vector inputs; - std::vector hash_values; - std::vector outputs; + std::array inputs; + std::array hash_values; + std::array outputs; friend bool operator==(const Sha256Compression&, const Sha256Compression&); std::vector bincodeSerialize() const; @@ -922,6 +922,9 @@ namespace Program { }; struct Trap { + uint64_t revert_data_offset; + uint64_t revert_data_size; + friend bool operator==(const Trap&, const Trap&); std::vector bincodeSerialize() const; static Trap bincodeDeserialize(std::vector); @@ -1061,6 +1064,17 @@ namespace Program { static MemoryInit bincodeDeserialize(std::vector); }; + struct BrilligCall { + uint32_t id; + std::vector inputs; + std::vector outputs; + std::optional predicate; + + friend bool operator==(const BrilligCall&, const BrilligCall&); + std::vector bincodeSerialize() const; + static BrilligCall bincodeDeserialize(std::vector); + }; + struct Call { uint32_t id; std::vector inputs; @@ -1072,7 +1086,7 @@ namespace Program { static Call bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const Opcode&, const Opcode&); std::vector bincodeSerialize() const; @@ -1151,8 +1165,17 @@ namespace Program { static Circuit bincodeDeserialize(std::vector); }; + struct BrilligBytecode { + std::vector bytecode; + + friend bool operator==(const BrilligBytecode&, const BrilligBytecode&); + std::vector bincodeSerialize() const; + static BrilligBytecode bincodeDeserialize(std::vector); + }; + struct Program { std::vector functions; + std::vector unconstrained_functions; friend bool operator==(const Program&, const Program&); std::vector bincodeSerialize() const; @@ -4071,6 +4094,48 @@ Program::Brillig serde::Deserializable::deserialize(Deserializ return obj; } +namespace Program { + + inline bool operator==(const BrilligBytecode &lhs, const BrilligBytecode &rhs) { + if (!(lhs.bytecode == rhs.bytecode)) { return false; } + return true; + } + + inline std::vector BrilligBytecode::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BrilligBytecode BrilligBytecode::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::BrilligBytecode &obj, Serializer &serializer) { + serializer.increase_container_depth(); + serde::Serializable::serialize(obj.bytecode, serializer); + serializer.decrease_container_depth(); +} + +template <> +template +Program::BrilligBytecode serde::Deserializable::deserialize(Deserializer &deserializer) { + deserializer.increase_container_depth(); + Program::BrilligBytecode obj; + obj.bytecode = serde::Deserializable::deserialize(deserializer); + deserializer.decrease_container_depth(); + return obj; +} + namespace Program { inline bool operator==(const BrilligInputs &lhs, const BrilligInputs &rhs) { @@ -4952,6 +5017,8 @@ Program::BrilligOpcode::BlackBox serde::Deserializable template void serde::Serializable::serialize(const Program::BrilligOpcode::Trap &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.revert_data_offset, serializer); + serde::Serializable::serialize(obj.revert_data_size, serializer); } template <> template Program::BrilligOpcode::Trap serde::Deserializable::deserialize(Deserializer &deserializer) { Program::BrilligOpcode::Trap obj; + obj.revert_data_offset = serde::Deserializable::deserialize(deserializer); + obj.revert_data_size = serde::Deserializable::deserialize(deserializer); return obj; } @@ -6118,6 +6189,53 @@ Program::Opcode::MemoryInit serde::Deserializable:: return obj; } +namespace Program { + + inline bool operator==(const Opcode::BrilligCall &lhs, const Opcode::BrilligCall &rhs) { + if (!(lhs.id == rhs.id)) { return false; } + if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.outputs == rhs.outputs)) { return false; } + if (!(lhs.predicate == rhs.predicate)) { return false; } + return true; + } + + inline std::vector Opcode::BrilligCall::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline Opcode::BrilligCall Opcode::BrilligCall::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Program + +template <> +template +void serde::Serializable::serialize(const Program::Opcode::BrilligCall &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.id, serializer); + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.outputs, serializer); + serde::Serializable::serialize(obj.predicate, serializer); +} + +template <> +template +Program::Opcode::BrilligCall serde::Deserializable::deserialize(Deserializer &deserializer) { + Program::Opcode::BrilligCall obj; + obj.id = serde::Deserializable::deserialize(deserializer); + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.outputs = serde::Deserializable::deserialize(deserializer); + obj.predicate = serde::Deserializable::deserialize(deserializer); + return obj; +} + namespace Program { inline bool operator==(const Opcode::Call &lhs, const Opcode::Call &rhs) { @@ -6290,6 +6408,7 @@ namespace Program { inline bool operator==(const Program &lhs, const Program &rhs) { if (!(lhs.functions == rhs.functions)) { return false; } + if (!(lhs.unconstrained_functions == rhs.unconstrained_functions)) { return false; } return true; } @@ -6315,6 +6434,7 @@ template void serde::Serializable::serialize(const Program::Program &obj, Serializer &serializer) { serializer.increase_container_depth(); serde::Serializable::serialize(obj.functions, serializer); + serde::Serializable::serialize(obj.unconstrained_functions, serializer); serializer.decrease_container_depth(); } @@ -6324,6 +6444,7 @@ Program::Program serde::Deserializable::deserialize(Deserializ deserializer.increase_container_depth(); Program::Program obj; obj.functions = serde::Deserializable::deserialize(deserializer); + obj.unconstrained_functions = serde::Deserializable::deserialize(deserializer); deserializer.decrease_container_depth(); return obj; } diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/brillig.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/brillig.rs index f394a46ff826..e75d335d52b6 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/brillig.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/brillig.rs @@ -29,3 +29,11 @@ pub struct Brillig { /// Predicate of the Brillig execution - indicates if it should be skipped pub predicate: Option, } + +/// This is purely a wrapper struct around a list of Brillig opcode's which represents +/// a full Brillig function to be executed by the Brillig VM. +/// This is stored separately on a program and accessed through a [BrilligPointer]. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +pub struct BrilligBytecode { + pub bytecode: Vec, +} diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs index cb846bdaffa6..d655d136bc8c 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs @@ -15,6 +15,8 @@ use serde::{de::Error as DeserializationError, Deserialize, Deserializer, Serial use std::collections::BTreeSet; +use self::brillig::BrilligBytecode; + /// Specifies the maximum width of the expressions which will be constrained. /// /// Unbounded Expressions are useful if you are eventually going to pass the ACIR @@ -37,6 +39,7 @@ pub enum ExpressionWidth { #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Default)] pub struct Program { pub functions: Vec, + pub unconstrained_functions: Vec, } #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Default)] @@ -86,6 +89,16 @@ impl Circuit { } } +#[derive(Debug, Copy, Clone)] +/// The opcode location for a call to a separate ACIR circuit +/// This includes the function index of the caller within a [program][Program] +/// and the index in the callers ACIR to the specific call opcode. +/// This is only resolved and set during circuit execution. +pub struct ResolvedOpcodeLocation { + pub acir_function_index: usize, + pub opcode_location: OpcodeLocation, +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] /// Opcodes are locatable so that callers can /// map opcodes to debug information related to their context. @@ -263,6 +276,10 @@ impl std::fmt::Display for Program { writeln!(f, "func {}", func_index)?; writeln!(f, "{}", function)?; } + for (func_index, function) in self.unconstrained_functions.iter().enumerate() { + writeln!(f, "unconstrained func {}", func_index)?; + writeln!(f, "{:?}", function.bytecode)?; + } Ok(()) } } @@ -314,61 +331,31 @@ mod tests { }) } fn keccakf1600_opcode() -> Opcode { - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Keccakf1600 { - inputs: vec![ - FunctionInput { witness: Witness(1), num_bits: 64 }, - FunctionInput { witness: Witness(2), num_bits: 64 }, - FunctionInput { witness: Witness(3), num_bits: 64 }, - FunctionInput { witness: Witness(4), num_bits: 64 }, - FunctionInput { witness: Witness(5), num_bits: 64 }, - FunctionInput { witness: Witness(6), num_bits: 64 }, - FunctionInput { witness: Witness(7), num_bits: 64 }, - FunctionInput { witness: Witness(8), num_bits: 64 }, - FunctionInput { witness: Witness(9), num_bits: 64 }, - FunctionInput { witness: Witness(10), num_bits: 64 }, - FunctionInput { witness: Witness(11), num_bits: 64 }, - FunctionInput { witness: Witness(12), num_bits: 64 }, - FunctionInput { witness: Witness(13), num_bits: 64 }, - FunctionInput { witness: Witness(14), num_bits: 64 }, - FunctionInput { witness: Witness(15), num_bits: 64 }, - FunctionInput { witness: Witness(16), num_bits: 64 }, - FunctionInput { witness: Witness(17), num_bits: 64 }, - FunctionInput { witness: Witness(18), num_bits: 64 }, - FunctionInput { witness: Witness(19), num_bits: 64 }, - FunctionInput { witness: Witness(20), num_bits: 64 }, - FunctionInput { witness: Witness(21), num_bits: 64 }, - FunctionInput { witness: Witness(22), num_bits: 64 }, - FunctionInput { witness: Witness(23), num_bits: 64 }, - FunctionInput { witness: Witness(24), num_bits: 64 }, - FunctionInput { witness: Witness(25), num_bits: 64 }, - ], - outputs: vec![ - Witness(26), - Witness(27), - Witness(28), - Witness(29), - Witness(30), - Witness(31), - Witness(32), - Witness(33), - Witness(34), - Witness(35), - Witness(36), - Witness(37), - Witness(38), - Witness(39), - Witness(40), - Witness(41), - Witness(42), - Witness(43), - Witness(44), - Witness(45), - Witness(46), - Witness(47), - Witness(48), - Witness(49), - Witness(50), - ], + let inputs: Box<[FunctionInput; 25]> = Box::new(std::array::from_fn(|i| FunctionInput { + witness: Witness(i as u32 + 1), + num_bits: 8, + })); + let outputs: Box<[Witness; 25]> = Box::new(std::array::from_fn(|i| Witness(i as u32 + 26))); + + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Keccakf1600 { inputs, outputs }) + } + fn schnorr_verify_opcode() -> Opcode { + let public_key_x = + FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }; + let public_key_y = + FunctionInput { witness: Witness(2), num_bits: FieldElement::max_num_bits() }; + let signature: Box<[FunctionInput; 64]> = Box::new(std::array::from_fn(|i| { + FunctionInput { witness: Witness(i as u32 + 3), num_bits: 8 } + })); + let message: Vec = vec![FunctionInput { witness: Witness(67), num_bits: 8 }]; + let output = Witness(68); + + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::SchnorrVerify { + public_key_x, + public_key_y, + signature, + message, + output, }) } @@ -377,14 +364,14 @@ mod tests { let circuit = Circuit { current_witness_index: 5, expression_width: ExpressionWidth::Unbounded, - opcodes: vec![and_opcode(), range_opcode()], + opcodes: vec![and_opcode(), range_opcode(), schnorr_verify_opcode()], private_parameters: BTreeSet::new(), public_parameters: PublicInputs(BTreeSet::from_iter(vec![Witness(2), Witness(12)])), return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(4), Witness(12)])), assert_messages: Default::default(), recursive: false, }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: Vec::new() }; fn read_write(program: Program) -> (Program, Program) { let bytes = Program::serialize_program(&program); @@ -410,6 +397,7 @@ mod tests { range_opcode(), and_opcode(), keccakf1600_opcode(), + schnorr_verify_opcode(), ], private_parameters: BTreeSet::new(), public_parameters: PublicInputs(BTreeSet::from_iter(vec![Witness(2)])), @@ -417,7 +405,7 @@ mod tests { assert_messages: Default::default(), recursive: false, }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: Vec::new() }; let json = serde_json::to_string_pretty(&program).unwrap(); diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs index d8204132b3ee..b0b8e286e0c2 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes.rs @@ -1,4 +1,7 @@ -use super::{brillig::Brillig, directives::Directive}; +use super::{ + brillig::{Brillig, BrilligInputs, BrilligOutputs}, + directives::Directive, +}; use crate::native_types::{Expression, Witness}; use serde::{Deserialize, Serialize}; @@ -29,6 +32,18 @@ pub enum Opcode { block_id: BlockId, init: Vec, }, + /// Calls to unconstrained functions + BrilligCall { + /// Id for the function being called. It is the responsibility of the executor + /// to fetch the appropriate Brillig bytecode from this id. + id: u32, + /// Inputs to the function call + inputs: Vec, + /// Outputs to the function call + outputs: Vec, + /// Predicate of the Brillig execution - indicates if it should be skipped + predicate: Option, + }, /// Calls to functions represented as a separate circuit. A call opcode allows us /// to build a call stack when executing the outer-most circuit. Call { @@ -99,6 +114,16 @@ impl std::fmt::Display for Opcode { write!(f, "INIT ")?; write!(f, "(id: {}, len: {}) ", block_id.0, init.len()) } + // We keep the display for a BrilligCall and circuit Call separate as they + // are distinct in their functionality and we should maintain this separation for debugging. + Opcode::BrilligCall { id, inputs, outputs, predicate } => { + write!(f, "BRILLIG CALL func {}: ", id)?; + if let Some(pred) = predicate { + writeln!(f, "PREDICATE = {pred}")?; + } + write!(f, "inputs: {:?}, ", inputs)?; + write!(f, "outputs: {:?}", outputs) + } Opcode::Call { id, inputs, outputs, predicate } => { write!(f, "CALL func {}: ", id)?; if let Some(pred) = predicate { 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 d90895787390..405cd0cef007 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 @@ -1,6 +1,6 @@ use crate::native_types::Witness; use crate::BlackBoxFunc; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; // Note: Some functions will not use all of the witness // So we need to supply how many bits of the witness is needed @@ -27,20 +27,24 @@ pub enum BlackBoxFuncCall { }, SHA256 { inputs: Vec, - outputs: Vec, + outputs: Box<[Witness; 32]>, }, Blake2s { inputs: Vec, - outputs: Vec, + outputs: Box<[Witness; 32]>, }, Blake3 { inputs: Vec, - outputs: Vec, + outputs: Box<[Witness; 32]>, }, SchnorrVerify { public_key_x: FunctionInput, public_key_y: FunctionInput, - signature: Vec, + #[serde( + serialize_with = "serialize_big_array", + deserialize_with = "deserialize_big_array_into_box" + )] + signature: Box<[FunctionInput; 64]>, message: Vec, output: Witness, }, @@ -55,17 +59,25 @@ pub enum BlackBoxFuncCall { output: Witness, }, EcdsaSecp256k1 { - public_key_x: Vec, - public_key_y: Vec, - signature: Vec, - hashed_message: Vec, + public_key_x: Box<[FunctionInput; 32]>, + public_key_y: Box<[FunctionInput; 32]>, + #[serde( + serialize_with = "serialize_big_array", + deserialize_with = "deserialize_big_array_into_box" + )] + signature: Box<[FunctionInput; 64]>, + hashed_message: Box<[FunctionInput; 32]>, output: Witness, }, EcdsaSecp256r1 { - public_key_x: Vec, - public_key_y: Vec, - signature: Vec, - hashed_message: Vec, + public_key_x: Box<[FunctionInput; 32]>, + public_key_y: Box<[FunctionInput; 32]>, + #[serde( + serialize_with = "serialize_big_array", + deserialize_with = "deserialize_big_array_into_box" + )] + signature: Box<[FunctionInput; 64]>, + hashed_message: Box<[FunctionInput; 32]>, output: Witness, }, FixedBaseScalarMul { @@ -87,11 +99,11 @@ pub enum BlackBoxFuncCall { /// is more than the number of bytes in the input, /// then an error is returned. var_message_size: FunctionInput, - outputs: Vec, + outputs: Box<[Witness; 32]>, }, Keccakf1600 { - inputs: Vec, - outputs: Vec, + inputs: Box<[FunctionInput; 25]>, + outputs: Box<[Witness; 25]>, }, RecursiveAggregation { verification_key: Vec, @@ -154,11 +166,11 @@ pub enum BlackBoxFuncCall { /// * `outputs` - result of the input compressed into 256 bits Sha256Compression { /// 512 bits of the input message, represented by 16 u32s - inputs: Vec, + inputs: Box<[FunctionInput; 16]>, /// Vector of 8 u32s used to compress the input - hash_values: Vec, + hash_values: Box<[FunctionInput; 8]>, /// Output of the compression, represented by 8 u32s - outputs: Vec, + outputs: Box<[Witness; 8]>, }, } @@ -201,13 +213,15 @@ impl BlackBoxFuncCall { BlackBoxFuncCall::SHA256 { inputs, .. } | BlackBoxFuncCall::Blake2s { inputs, .. } | BlackBoxFuncCall::Blake3 { inputs, .. } - | BlackBoxFuncCall::Keccakf1600 { inputs, .. } | BlackBoxFuncCall::PedersenCommitment { inputs, .. } | BlackBoxFuncCall::PedersenHash { inputs, .. } | BlackBoxFuncCall::BigIntFromLeBytes { inputs, .. } | BlackBoxFuncCall::Poseidon2Permutation { inputs, .. } => inputs.to_vec(), + + BlackBoxFuncCall::Keccakf1600 { inputs, .. } => inputs.to_vec(), + BlackBoxFuncCall::Sha256Compression { inputs, hash_values, .. } => { - inputs.iter().chain(hash_values).copied().collect() + inputs.iter().chain(hash_values.as_ref()).copied().collect() } BlackBoxFuncCall::AND { lhs, rhs, .. } | BlackBoxFuncCall::XOR { lhs, rhs, .. } => { vec![*lhs, *rhs] @@ -300,10 +314,14 @@ impl BlackBoxFuncCall { BlackBoxFuncCall::SHA256 { outputs, .. } | BlackBoxFuncCall::Blake2s { outputs, .. } | BlackBoxFuncCall::Blake3 { outputs, .. } - | BlackBoxFuncCall::Keccakf1600 { outputs, .. } - | BlackBoxFuncCall::Keccak256 { outputs, .. } - | BlackBoxFuncCall::Poseidon2Permutation { outputs, .. } - | BlackBoxFuncCall::Sha256Compression { outputs, .. } => outputs.to_vec(), + | BlackBoxFuncCall::Keccak256 { outputs, .. } => outputs.to_vec(), + + BlackBoxFuncCall::Keccakf1600 { outputs, .. } => outputs.to_vec(), + + BlackBoxFuncCall::Sha256Compression { outputs, .. } => outputs.to_vec(), + + BlackBoxFuncCall::Poseidon2Permutation { outputs, .. } => outputs.to_vec(), + BlackBoxFuncCall::AND { output, .. } | BlackBoxFuncCall::XOR { output, .. } | BlackBoxFuncCall::SchnorrVerify { output, .. } @@ -422,3 +440,78 @@ impl std::fmt::Debug for BlackBoxFuncCall { std::fmt::Display::fmt(self, f) } } + +fn serialize_big_array(big_array: &[FunctionInput; 64], s: S) -> Result +where + S: Serializer, +{ + use serde_big_array::BigArray; + + (*big_array).serialize(s) +} + +fn deserialize_big_array_into_box<'de, D>( + deserializer: D, +) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + use serde_big_array::BigArray; + + let big_array: [FunctionInput; 64] = BigArray::deserialize(deserializer)?; + Ok(Box::new(big_array)) +} + +#[cfg(test)] +mod tests { + + use crate::{circuit::Opcode, native_types::Witness}; + use acir_field::FieldElement; + + use super::{BlackBoxFuncCall, FunctionInput}; + + fn keccakf1600_opcode() -> Opcode { + let inputs: Box<[FunctionInput; 25]> = Box::new(std::array::from_fn(|i| FunctionInput { + witness: Witness(i as u32 + 1), + num_bits: 8, + })); + let outputs: Box<[Witness; 25]> = Box::new(std::array::from_fn(|i| Witness(i as u32 + 26))); + + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Keccakf1600 { inputs, outputs }) + } + fn schnorr_verify_opcode() -> Opcode { + let public_key_x = + FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }; + let public_key_y = + FunctionInput { witness: Witness(2), num_bits: FieldElement::max_num_bits() }; + let signature: Box<[FunctionInput; 64]> = Box::new(std::array::from_fn(|i| { + FunctionInput { witness: Witness(i as u32 + 3), num_bits: 8 } + })); + let message: Vec = vec![FunctionInput { witness: Witness(67), num_bits: 8 }]; + let output = Witness(68); + + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::SchnorrVerify { + public_key_x, + public_key_y, + signature, + message, + output, + }) + } + + #[test] + fn keccakf1600_serialization_roundtrip() { + let opcode = keccakf1600_opcode(); + let buf = bincode::serialize(&opcode).unwrap(); + let recovered_opcode = bincode::deserialize(&buf).unwrap(); + assert_eq!(opcode, recovered_opcode); + } + + #[test] + fn schnorr_serialization_roundtrip() { + let opcode = schnorr_verify_opcode(); + let buf = bincode::serialize(&opcode).unwrap(); + let recovered_opcode = bincode::deserialize(&buf).unwrap(); + assert_eq!(opcode, recovered_opcode); + } +} 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 8b9160ccf6a4..fb924a7437d3 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 @@ -41,17 +41,17 @@ fn addition_circuit() { return_values: PublicInputs([Witness(3)].into()), ..Circuit::default() }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 75, 14, 128, 32, 12, 68, 249, 120, 160, 150, - 182, 208, 238, 188, 138, 68, 184, 255, 17, 212, 200, 130, 196, 165, 188, 164, 153, 174, 94, - 38, 227, 221, 203, 118, 159, 119, 95, 226, 200, 125, 36, 252, 3, 253, 66, 87, 152, 92, 4, - 153, 185, 149, 212, 144, 240, 128, 100, 85, 5, 88, 106, 86, 84, 20, 149, 51, 41, 81, 83, - 214, 98, 213, 10, 24, 50, 53, 236, 98, 212, 135, 44, 174, 235, 5, 143, 35, 12, 151, 159, - 126, 55, 109, 28, 231, 145, 47, 245, 105, 191, 143, 133, 1, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 65, 14, 128, 32, 12, 4, 65, 124, 80, 75, 91, + 104, 111, 126, 69, 34, 252, 255, 9, 106, 228, 64, 162, 55, 153, 164, 217, 158, 38, 155, + 245, 238, 97, 189, 206, 187, 55, 161, 231, 214, 19, 254, 129, 126, 162, 107, 25, 92, 4, + 137, 185, 230, 88, 145, 112, 135, 104, 69, 5, 88, 74, 82, 84, 20, 149, 35, 42, 81, 85, 214, + 108, 197, 50, 24, 50, 85, 108, 98, 212, 186, 44, 204, 235, 5, 183, 99, 233, 46, 63, 252, + 110, 216, 56, 184, 15, 78, 146, 74, 173, 20, 141, 1, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -72,14 +72,14 @@ fn fixed_base_scalar_mul_circuit() { return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(3), Witness(4)])), ..Circuit::default() }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 138, 81, 10, 0, 48, 8, 66, 87, 219, 190, 118, 233, - 29, 61, 43, 3, 5, 121, 34, 207, 86, 231, 162, 198, 157, 124, 228, 71, 157, 220, 232, 161, - 227, 226, 206, 214, 95, 221, 74, 0, 116, 58, 13, 182, 105, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 138, 81, 10, 0, 48, 8, 66, 87, 219, 190, 118, 233, + 29, 61, 35, 3, 19, 228, 137, 60, 91, 149, 139, 26, 119, 242, 145, 31, 117, 114, 163, 135, + 142, 139, 219, 91, 127, 117, 71, 2, 117, 84, 50, 98, 113, 0, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -100,14 +100,14 @@ fn pedersen_circuit() { return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(2), Witness(3)])), ..Circuit::default() }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 74, 7, 6, 0, 0, 8, 108, 209, 255, 63, 156, 54, 233, - 56, 55, 17, 26, 18, 196, 241, 169, 250, 178, 141, 167, 32, 159, 254, 234, 238, 255, 87, - 112, 52, 63, 63, 101, 105, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 74, 9, 10, 0, 0, 4, 115, 149, 255, 127, 88, 8, 133, + 213, 218, 137, 80, 144, 32, 182, 79, 213, 151, 173, 61, 5, 121, 245, 91, 103, 255, 191, 3, + 7, 16, 26, 112, 158, 113, 0, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -119,8 +119,11 @@ fn schnorr_verify_circuit() { FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }; let public_key_y = FunctionInput { witness: Witness(2), num_bits: FieldElement::max_num_bits() }; - let signature = - (3..(3 + 64)).map(|i| FunctionInput { witness: Witness(i), num_bits: 8 }).collect(); + let signature: [FunctionInput; 64] = (3..(3 + 64)) + .map(|i| FunctionInput { witness: Witness(i), num_bits: 8 }) + .collect::>() + .try_into() + .unwrap(); let message = ((3 + 64)..(3 + 64 + 10)) .map(|i| FunctionInput { witness: Witness(i), num_bits: 8 }) .collect(); @@ -130,7 +133,7 @@ fn schnorr_verify_circuit() { let schnorr = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::SchnorrVerify { public_key_x, public_key_y, - signature, + signature: Box::new(signature), message, output, }); @@ -142,27 +145,27 @@ fn schnorr_verify_circuit() { return_values: PublicInputs(BTreeSet::from([output])), ..Circuit::default() }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 210, 7, 78, 2, 1, 20, 69, 81, 236, 189, 247, 222, - 123, 239, 93, 177, 33, 34, 238, 194, 253, 47, 193, 200, 147, 67, 194, 36, 147, 163, 33, 33, - 228, 191, 219, 82, 168, 63, 63, 181, 183, 197, 223, 177, 147, 191, 181, 183, 149, 69, 159, - 183, 213, 222, 238, 218, 219, 206, 14, 118, 178, 139, 141, 183, 135, 189, 236, 99, 63, 7, - 56, 200, 33, 14, 115, 132, 163, 28, 227, 56, 39, 56, 201, 41, 78, 115, 134, 179, 156, 227, - 60, 23, 184, 200, 37, 46, 115, 133, 171, 92, 227, 58, 55, 184, 201, 45, 110, 115, 135, 187, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 210, 85, 78, 67, 81, 24, 133, 209, 226, 238, 238, + 238, 238, 238, 165, 148, 82, 102, 193, 252, 135, 64, 232, 78, 87, 147, 114, 147, 147, 5, + 47, 132, 252, 251, 107, 41, 212, 191, 159, 218, 107, 241, 115, 236, 228, 111, 237, 181, + 178, 173, 246, 186, 107, 175, 157, 29, 236, 100, 23, 27, 175, 135, 189, 236, 99, 63, 7, 56, + 200, 33, 14, 115, 132, 163, 28, 227, 56, 39, 56, 201, 41, 78, 115, 134, 179, 156, 227, 60, + 23, 184, 200, 37, 46, 115, 133, 171, 92, 227, 58, 55, 184, 201, 45, 110, 115, 135, 187, 220, 227, 62, 15, 120, 200, 35, 30, 243, 132, 167, 60, 227, 57, 47, 120, 201, 43, 94, 243, - 134, 183, 188, 227, 61, 31, 248, 200, 39, 22, 249, 204, 151, 166, 29, 243, 188, 250, 255, - 141, 239, 44, 241, 131, 101, 126, 178, 194, 47, 86, 249, 237, 123, 171, 76, 127, 105, 47, - 189, 165, 181, 116, 150, 198, 26, 125, 245, 248, 45, 233, 41, 45, 165, 163, 52, 148, 126, - 210, 78, 186, 73, 51, 233, 37, 173, 164, 147, 52, 146, 62, 210, 70, 186, 72, 19, 233, 33, - 45, 164, 131, 52, 144, 253, 151, 11, 245, 221, 179, 121, 246, 206, 214, 217, 57, 27, 103, - 223, 109, 187, 238, 218, 115, 223, 142, 135, 246, 59, 182, 219, 169, 189, 206, 237, 116, - 105, 159, 107, 187, 220, 218, 227, 222, 14, 143, 238, 95, 116, 247, 23, 119, 126, 115, 223, - 146, 187, 150, 221, 179, 226, 142, 141, 155, 53, 238, 86, 104, 186, 231, 255, 243, 7, 100, - 141, 232, 192, 233, 3, 0, 0, + 134, 183, 188, 227, 61, 31, 248, 200, 39, 62, 243, 133, 175, 77, 59, 230, 123, 243, 123, + 145, 239, 44, 241, 131, 101, 126, 178, 194, 47, 86, 249, 237, 239, 86, 153, 238, 210, 92, + 122, 75, 107, 233, 44, 141, 53, 250, 234, 241, 191, 164, 167, 180, 148, 142, 210, 80, 250, + 73, 59, 233, 38, 205, 164, 151, 180, 146, 78, 210, 72, 250, 72, 27, 233, 34, 77, 164, 135, + 180, 144, 14, 210, 64, 246, 95, 46, 212, 119, 207, 230, 217, 59, 91, 103, 231, 108, 156, + 125, 183, 237, 186, 107, 207, 125, 59, 30, 218, 239, 216, 110, 167, 246, 58, 183, 211, 165, + 125, 174, 237, 114, 107, 143, 123, 59, 60, 186, 255, 179, 187, 191, 186, 115, 209, 125, 75, + 238, 90, 118, 207, 138, 59, 54, 110, 214, 184, 91, 161, 233, 158, 255, 190, 63, 165, 188, + 93, 151, 233, 3, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -206,16 +209,17 @@ fn simple_brillig_foreign_call() { private_parameters: BTreeSet::from([Witness(1), Witness(2)]), ..Circuit::default() }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 61, 10, 192, 48, 8, 133, 53, 133, 82, 186, - 245, 38, 233, 13, 122, 153, 14, 93, 58, 132, 144, 227, 135, 252, 41, 56, 36, 46, 201, 7, - 162, 168, 200, 123, 34, 52, 142, 28, 72, 245, 38, 106, 9, 247, 30, 202, 118, 142, 27, 215, - 221, 178, 82, 175, 33, 15, 133, 189, 163, 159, 57, 197, 252, 251, 195, 235, 188, 230, 186, - 16, 65, 255, 12, 239, 92, 131, 89, 149, 198, 77, 3, 10, 9, 119, 8, 198, 242, 152, 1, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 61, 10, 192, 32, 12, 133, 19, 11, 165, 116, + 235, 77, 236, 13, 122, 153, 14, 93, 58, 136, 120, 124, 241, 47, 129, 12, 42, 130, 126, 16, + 18, 146, 16, 222, 11, 66, 225, 136, 129, 84, 111, 162, 150, 112, 239, 161, 172, 231, 184, + 113, 221, 45, 45, 245, 42, 242, 144, 216, 43, 250, 153, 83, 204, 191, 223, 189, 198, 246, + 92, 39, 60, 244, 63, 195, 59, 87, 99, 150, 165, 113, 83, 193, 0, 1, 19, 247, 29, 5, 160, 1, + 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -306,20 +310,20 @@ fn complex_brillig_foreign_call() { private_parameters: BTreeSet::from([Witness(1), Witness(2), Witness(3)]), ..Circuit::default() }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 84, 93, 10, 131, 48, 12, 78, 218, 233, 100, 111, - 187, 193, 96, 59, 64, 231, 9, 188, 139, 248, 166, 232, 163, 167, 23, 11, 126, 197, 24, 250, - 34, 86, 208, 64, 72, 218, 252, 125, 36, 105, 153, 22, 42, 60, 51, 116, 235, 217, 64, 103, - 156, 37, 5, 191, 10, 210, 29, 163, 63, 167, 203, 229, 206, 194, 104, 110, 128, 209, 158, - 128, 49, 236, 195, 69, 231, 157, 114, 46, 73, 251, 103, 35, 239, 231, 225, 57, 243, 156, - 227, 252, 132, 44, 112, 79, 176, 125, 84, 223, 73, 248, 145, 152, 69, 149, 4, 107, 233, - 114, 90, 119, 145, 85, 237, 151, 192, 89, 247, 221, 208, 54, 163, 85, 174, 26, 234, 87, - 232, 63, 101, 103, 21, 55, 169, 216, 73, 72, 249, 5, 197, 234, 132, 123, 179, 35, 247, 155, - 214, 246, 102, 20, 73, 204, 72, 168, 123, 191, 161, 25, 66, 136, 159, 187, 53, 5, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 84, 75, 10, 132, 48, 12, 77, 218, 209, 145, 217, + 205, 13, 6, 198, 3, 84, 79, 224, 93, 196, 157, 162, 75, 79, 47, 22, 124, 197, 16, 186, 17, + 43, 104, 32, 36, 109, 126, 143, 36, 45, 211, 70, 133, 103, 134, 110, 61, 27, 232, 140, 179, + 164, 224, 215, 64, 186, 115, 84, 113, 186, 92, 238, 42, 140, 230, 1, 24, 237, 5, 24, 195, + 62, 220, 116, 222, 41, 231, 146, 180, 127, 54, 242, 126, 94, 158, 51, 207, 57, 206, 111, + 200, 2, 247, 4, 219, 79, 245, 157, 132, 31, 137, 89, 52, 73, 176, 214, 46, 167, 125, 23, + 89, 213, 254, 8, 156, 237, 56, 76, 125, 55, 91, 229, 170, 161, 254, 133, 94, 42, 59, 171, + 184, 69, 197, 46, 66, 202, 47, 40, 86, 39, 220, 155, 3, 185, 191, 180, 183, 55, 163, 72, + 98, 70, 66, 221, 251, 40, 173, 255, 35, 68, 62, 61, 5, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -348,16 +352,16 @@ fn memory_op_circuit() { return_values: PublicInputs([Witness(4)].into()), ..Circuit::default() }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 81, 201, 13, 0, 32, 8, 147, 195, 125, 112, 3, 247, - 159, 74, 141, 60, 106, 226, 79, 120, 216, 132, 180, 124, 154, 82, 168, 108, 212, 57, 2, - 122, 129, 157, 201, 181, 150, 59, 186, 179, 189, 161, 101, 251, 82, 176, 175, 196, 121, 89, - 118, 185, 246, 91, 185, 26, 125, 187, 64, 80, 134, 29, 195, 31, 79, 24, 2, 250, 167, 252, - 27, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 81, 57, 14, 0, 32, 8, 147, 195, 255, 224, 15, 252, + 255, 171, 212, 200, 208, 129, 77, 24, 108, 66, 90, 150, 166, 20, 106, 23, 125, 143, 128, + 62, 96, 103, 114, 173, 45, 198, 116, 182, 55, 140, 106, 95, 74, 246, 149, 60, 47, 171, 46, + 215, 126, 43, 87, 179, 111, 23, 8, 202, 176, 99, 248, 240, 9, 11, 137, 33, 212, 110, 35, 3, + 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -450,20 +454,21 @@ fn nested_acir_call_circuit() { ..Circuit::default() }; - let program = Program { functions: vec![main, nested_call, inner_call] }; + let program = + Program { functions: vec![main, nested_call, inner_call], unconstrained_functions: vec![] }; let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 205, 146, 65, 10, 3, 33, 12, 69, 163, 46, 230, 58, 137, + 209, 49, 238, 122, 149, 74, 157, 251, 31, 161, 83, 154, 161, 86, 132, 89, 212, 194, 124, + 248, 24, 36, 132, 228, 241, 29, 188, 229, 212, 47, 45, 187, 205, 110, 11, 31, 25, 53, 28, + 255, 103, 77, 14, 58, 29, 141, 55, 125, 241, 55, 145, 109, 102, 49, 174, 33, 212, 228, 43, + 49, 221, 209, 231, 34, 17, 67, 44, 171, 144, 80, 148, 248, 240, 194, 92, 37, 72, 202, 37, + 39, 204, 20, 184, 210, 22, 51, 111, 58, 204, 205, 219, 11, 161, 129, 208, 214, 6, 6, 114, + 29, 193, 127, 193, 130, 137, 176, 236, 188, 189, 252, 162, 183, 218, 230, 238, 97, 138, + 250, 152, 245, 245, 87, 220, 12, 140, 113, 95, 153, 170, 129, 185, 17, 60, 3, 54, 212, 19, + 104, 145, 195, 151, 14, 4, 0, 0, ]; assert_eq!(bytes, expected_serialization); } diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs index 003cd4279a11..d13fac1672a3 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/transformers/mod.rs @@ -142,6 +142,21 @@ pub(super) fn transform_internal( new_acir_opcode_positions.push(acir_opcode_positions[index]); transformed_opcodes.push(opcode); } + Opcode::BrilligCall { ref outputs, .. } => { + for output in outputs { + match output { + BrilligOutputs::Simple(w) => transformer.mark_solvable(*w), + BrilligOutputs::Array(v) => { + for witness in v { + transformer.mark_solvable(*witness); + } + } + } + } + + new_acir_opcode_positions.push(acir_opcode_positions[index]); + transformed_opcodes.push(opcode); + } Opcode::Call { ref outputs, .. } => { for witness in outputs { transformer.mark_solvable(*witness); diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/bigint.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/bigint.rs index f094bb1ba20f..3c05fb2761d1 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/bigint.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/bigint.rs @@ -1,53 +1,23 @@ -use std::collections::HashMap; - use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, BlackBoxFunc, FieldElement, }; -use num_bigint::BigUint; +use acvm_blackbox_solver::BigIntSolver; use crate::pwg::OpcodeResolutionError; -/// Resolve BigInt opcodes by storing BigInt values (and their moduli) by their ID in a HashMap: +/// Resolve BigInt opcodes by storing BigInt values (and their moduli) by their ID in the BigIntSolver /// - When it encounters a bigint operation opcode, it performs the operation on the stored values /// and store the result using the provided ID. /// - When it gets a to_bytes opcode, it simply looks up the value and resolves the output witness accordingly. #[derive(Default)] -pub(crate) struct BigIntSolver { - bigint_id_to_value: HashMap, - bigint_id_to_modulus: HashMap, +pub(crate) struct AcvmBigIntSolver { + bigint_solver: BigIntSolver, } -impl BigIntSolver { - pub(crate) fn get_bigint( - &self, - id: u32, - func: BlackBoxFunc, - ) -> Result { - self.bigint_id_to_value - .get(&id) - .ok_or(OpcodeResolutionError::BlackBoxFunctionFailed( - func, - format!("could not find bigint of id {id}"), - )) - .cloned() - } - - pub(crate) fn get_modulus( - &self, - id: u32, - func: BlackBoxFunc, - ) -> Result { - self.bigint_id_to_modulus - .get(&id) - .ok_or(OpcodeResolutionError::BlackBoxFunctionFailed( - func, - format!("could not find bigint of id {id}"), - )) - .cloned() - } +impl AcvmBigIntSolver { pub(crate) fn bigint_from_bytes( &mut self, inputs: &[FunctionInput], @@ -59,10 +29,7 @@ impl BigIntSolver { .iter() .map(|input| initial_witness.get(&input.witness).unwrap().to_u128() as u8) .collect::>(); - let bigint = BigUint::from_bytes_le(&bytes); - self.bigint_id_to_value.insert(output, bigint); - let modulus = BigUint::from_bytes_le(modulus); - self.bigint_id_to_modulus.insert(output, modulus); + self.bigint_solver.bigint_from_bytes(&bytes, modulus, output)?; Ok(()) } @@ -72,9 +39,7 @@ impl BigIntSolver { outputs: &[Witness], initial_witness: &mut WitnessMap, ) -> Result<(), OpcodeResolutionError> { - let bigint = self.get_bigint(input, BlackBoxFunc::BigIntToLeBytes)?; - - let mut bytes = bigint.to_bytes_le(); + let mut bytes = self.bigint_solver.bigint_to_bytes(input)?; while bytes.len() < outputs.len() { bytes.push(0); } @@ -91,30 +56,7 @@ impl BigIntSolver { output: u32, func: BlackBoxFunc, ) -> Result<(), OpcodeResolutionError> { - let modulus = self.get_modulus(lhs, func)?; - let lhs = self.get_bigint(lhs, func)?; - let rhs = self.get_bigint(rhs, func)?; - let mut result = match func { - BlackBoxFunc::BigIntAdd => lhs + rhs, - BlackBoxFunc::BigIntSub => { - if lhs >= rhs { - &lhs - &rhs - } else { - &lhs + &modulus - &rhs - } - } - BlackBoxFunc::BigIntMul => lhs * rhs, - BlackBoxFunc::BigIntDiv => { - lhs * rhs.modpow(&(&modulus - BigUint::from(1_u32)), &modulus) - } //TODO ensure that modulus is prime - _ => unreachable!("ICE - bigint_op must be called for an operation"), - }; - if result > modulus { - let q = &result / &modulus; - result -= q * &modulus; - } - self.bigint_id_to_value.insert(output, result); - self.bigint_id_to_modulus.insert(output, modulus); + self.bigint_solver.bigint_op(lhs, rhs, output, func)?; Ok(()) } } diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/hash.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/hash.rs index 24c835a636ad..caa09ea8973c 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/hash.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/hash.rs @@ -1,7 +1,7 @@ use acir::{ circuit::opcodes::FunctionInput, native_types::{Witness, WitnessMap}, - BlackBoxFunc, FieldElement, + FieldElement, }; use acvm_blackbox_solver::{sha256compression, BlackBoxFunctionSolver, BlackBoxResolutionError}; @@ -14,22 +14,13 @@ pub(super) fn solve_generic_256_hash_opcode( initial_witness: &mut WitnessMap, inputs: &[FunctionInput], var_message_size: Option<&FunctionInput>, - outputs: &[Witness], + outputs: &[Witness; 32], hash_function: fn(data: &[u8]) -> Result<[u8; 32], BlackBoxResolutionError>, - black_box_func: BlackBoxFunc, ) -> Result<(), OpcodeResolutionError> { let message_input = get_hash_input(initial_witness, inputs, var_message_size)?; let digest: [u8; 32] = hash_function(&message_input)?; - let outputs: [Witness; 32] = outputs.try_into().map_err(|_| { - OpcodeResolutionError::BlackBoxFunctionFailed( - black_box_func, - format!("Expected 32 outputs but encountered {}", outputs.len()), - ) - })?; - write_digest_to_outputs(initial_witness, outputs, digest)?; - - Ok(()) + write_digest_to_outputs(initial_witness, outputs, digest) } /// Reads the hash function input from a [`WitnessMap`]. @@ -73,7 +64,7 @@ fn get_hash_input( /// Writes a `digest` to the [`WitnessMap`] at witness indices `outputs`. fn write_digest_to_outputs( initial_witness: &mut WitnessMap, - outputs: [Witness; 32], + outputs: &[Witness; 32], digest: [u8; 32], ) -> Result<(), OpcodeResolutionError> { for (output_witness, value) in outputs.iter().zip(digest.into_iter()) { @@ -87,44 +78,29 @@ fn write_digest_to_outputs( Ok(()) } +fn to_u32_array( + initial_witness: &WitnessMap, + inputs: &[FunctionInput; N], +) -> Result<[u32; N], OpcodeResolutionError> { + let mut result = [0; N]; + for (it, input) in result.iter_mut().zip(inputs) { + let witness_value = witness_to_value(initial_witness, input.witness)?; + *it = witness_value.to_u128() as u32; + } + Ok(result) +} + pub(crate) fn solve_sha_256_permutation_opcode( initial_witness: &mut WitnessMap, - inputs: &[FunctionInput], - hash_values: &[FunctionInput], - outputs: &[Witness], - black_box_func: BlackBoxFunc, + inputs: &[FunctionInput; 16], + hash_values: &[FunctionInput; 8], + outputs: &[Witness; 8], ) -> Result<(), OpcodeResolutionError> { - let mut message = [0; 16]; - if inputs.len() != 16 { - return Err(OpcodeResolutionError::BlackBoxFunctionFailed( - black_box_func, - format!("Expected 16 inputs but encountered {}", &message.len()), - )); - } - for (i, input) in inputs.iter().enumerate() { - let value = witness_to_value(initial_witness, input.witness)?; - message[i] = value.to_u128() as u32; - } - - if hash_values.len() != 8 { - return Err(OpcodeResolutionError::BlackBoxFunctionFailed( - black_box_func, - format!("Expected 8 values but encountered {}", hash_values.len()), - )); - } - let mut state = [0; 8]; - for (i, hash) in hash_values.iter().enumerate() { - let value = witness_to_value(initial_witness, hash.witness)?; - state[i] = value.to_u128() as u32; - } + let message = to_u32_array(initial_witness, inputs)?; + let mut state = to_u32_array(initial_witness, hash_values)?; sha256compression(&mut state, &message); - let outputs: [Witness; 8] = outputs.try_into().map_err(|_| { - OpcodeResolutionError::BlackBoxFunctionFailed( - black_box_func, - format!("Expected 8 outputs but encountered {}", outputs.len()), - ) - })?; + for (output_witness, value) in outputs.iter().zip(state.into_iter()) { insert_value(output_witness, FieldElement::from(value as u128), initial_witness)?; } diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs index e7ed402a8ebd..2753c7baaaa9 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -6,7 +6,7 @@ use acir::{ use acvm_blackbox_solver::{blake2s, blake3, keccak256, keccakf1600, sha256}; use self::{ - bigint::BigIntSolver, hash::solve_poseidon2_permutation_opcode, pedersen::pedersen_hash, + bigint::AcvmBigIntSolver, hash::solve_poseidon2_permutation_opcode, pedersen::pedersen_hash, }; use super::{insert_value, OpcodeNotSolvable, OpcodeResolutionError}; @@ -56,7 +56,7 @@ pub(crate) fn solve( backend: &impl BlackBoxFunctionSolver, initial_witness: &mut WitnessMap, bb_func: &BlackBoxFuncCall, - bigint_solver: &mut BigIntSolver, + bigint_solver: &mut AcvmBigIntSolver, ) -> Result<(), OpcodeResolutionError> { let inputs = bb_func.get_inputs_vec(); if !contains_all_inputs(initial_witness, &inputs) { @@ -71,30 +71,16 @@ pub(crate) fn solve( BlackBoxFuncCall::AND { lhs, rhs, output } => and(initial_witness, lhs, rhs, output), BlackBoxFuncCall::XOR { lhs, rhs, output } => xor(initial_witness, lhs, rhs, output), BlackBoxFuncCall::RANGE { input } => solve_range_opcode(initial_witness, input), - BlackBoxFuncCall::SHA256 { inputs, outputs } => solve_generic_256_hash_opcode( - initial_witness, - inputs, - None, - outputs, - sha256, - bb_func.get_black_box_func(), - ), - BlackBoxFuncCall::Blake2s { inputs, outputs } => solve_generic_256_hash_opcode( - initial_witness, - inputs, - None, - outputs, - blake2s, - bb_func.get_black_box_func(), - ), - BlackBoxFuncCall::Blake3 { inputs, outputs } => solve_generic_256_hash_opcode( - initial_witness, - inputs, - None, - outputs, - blake3, - bb_func.get_black_box_func(), - ), + BlackBoxFuncCall::SHA256 { inputs, outputs } => { + solve_generic_256_hash_opcode(initial_witness, inputs, None, outputs, sha256) + } + BlackBoxFuncCall::Blake2s { inputs, outputs } => { + solve_generic_256_hash_opcode(initial_witness, inputs, None, outputs, blake2s) + } + BlackBoxFuncCall::Blake3 { inputs, outputs } => { + solve_generic_256_hash_opcode(initial_witness, inputs, None, outputs, blake3) + } + BlackBoxFuncCall::Keccak256 { inputs, var_message_size, outputs } => { solve_generic_256_hash_opcode( initial_witness, @@ -102,18 +88,17 @@ pub(crate) fn solve( Some(var_message_size), outputs, keccak256, - bb_func.get_black_box_func(), ) } BlackBoxFuncCall::Keccakf1600 { inputs, outputs } => { let mut state = [0; 25]; - for (i, input) in inputs.iter().enumerate() { + for (it, input) in state.iter_mut().zip(inputs.as_ref()) { let witness = input.witness; let num_bits = input.num_bits as usize; assert_eq!(num_bits, 64); let witness_assignment = witness_to_value(initial_witness, witness)?; let lane = witness_assignment.try_to_u64(); - state[i] = lane.unwrap(); + *it = lane.unwrap(); } let output_state = keccakf1600(state)?; for (output_witness, value) in outputs.iter().zip(output_state.into_iter()) { @@ -132,7 +117,7 @@ pub(crate) fn solve( initial_witness, *public_key_x, *public_key_y, - signature, + signature.as_ref(), message, *output, ), @@ -153,7 +138,7 @@ pub(crate) fn solve( public_key_x, public_key_y, signature, - message, + message.as_ref(), *output, ), BlackBoxFuncCall::EcdsaSecp256r1 { @@ -167,7 +152,7 @@ pub(crate) fn solve( public_key_x, public_key_y, signature, - message, + message.as_ref(), *output, ), BlackBoxFuncCall::FixedBaseScalarMul { low, high, outputs } => { @@ -199,13 +184,7 @@ pub(crate) fn solve( bigint_solver.bigint_to_bytes(*input, outputs, initial_witness) } BlackBoxFuncCall::Sha256Compression { inputs, hash_values, outputs } => { - solve_sha_256_permutation_opcode( - initial_witness, - inputs, - hash_values, - outputs, - bb_func.get_black_box_func(), - ) + solve_sha_256_permutation_opcode(initial_witness, inputs, hash_values, outputs) } BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs, len } => { solve_poseidon2_permutation_opcode(backend, initial_witness, inputs, outputs, *len) diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs index 8f0df8378adb..b113c8012512 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs @@ -7,85 +7,42 @@ use acvm_blackbox_solver::{ecdsa_secp256k1_verify, ecdsa_secp256r1_verify}; use crate::{pwg::insert_value, OpcodeResolutionError}; -use super::to_u8_vec; +use super::{to_u8_array, to_u8_vec}; pub(crate) fn secp256k1_prehashed( initial_witness: &mut WitnessMap, - public_key_x_inputs: &[FunctionInput], - public_key_y_inputs: &[FunctionInput], - signature_inputs: &[FunctionInput], + public_key_x_inputs: &[FunctionInput; 32], + public_key_y_inputs: &[FunctionInput; 32], + signature_inputs: &[FunctionInput; 64], hashed_message_inputs: &[FunctionInput], output: Witness, ) -> Result<(), OpcodeResolutionError> { let hashed_message = to_u8_vec(initial_witness, hashed_message_inputs)?; - // These errors should never be emitted in practice as they would imply malformed ACIR generation. - let pub_key_x: [u8; 32] = - to_u8_vec(initial_witness, public_key_x_inputs)?.try_into().map_err(|_| { - OpcodeResolutionError::BlackBoxFunctionFailed( - acir::BlackBoxFunc::EcdsaSecp256k1, - format!("expected pubkey_x size 32 but received {}", public_key_x_inputs.len()), - ) - })?; - - let pub_key_y: [u8; 32] = - to_u8_vec(initial_witness, public_key_y_inputs)?.try_into().map_err(|_| { - OpcodeResolutionError::BlackBoxFunctionFailed( - acir::BlackBoxFunc::EcdsaSecp256k1, - format!("expected pubkey_y size 32 but received {}", public_key_y_inputs.len()), - ) - })?; - - let signature: [u8; 64] = - to_u8_vec(initial_witness, signature_inputs)?.try_into().map_err(|_| { - OpcodeResolutionError::BlackBoxFunctionFailed( - acir::BlackBoxFunc::EcdsaSecp256k1, - format!("expected signature size 64 but received {}", signature_inputs.len()), - ) - })?; + let pub_key_x: [u8; 32] = to_u8_array(initial_witness, public_key_x_inputs)?; + let pub_key_y: [u8; 32] = to_u8_array(initial_witness, public_key_y_inputs)?; + let signature: [u8; 64] = to_u8_array(initial_witness, signature_inputs)?; let is_valid = ecdsa_secp256k1_verify(&hashed_message, &pub_key_x, &pub_key_y, &signature)?; - insert_value(&output, FieldElement::from(is_valid), initial_witness)?; - Ok(()) + insert_value(&output, FieldElement::from(is_valid), initial_witness) } pub(crate) fn secp256r1_prehashed( initial_witness: &mut WitnessMap, - public_key_x_inputs: &[FunctionInput], - public_key_y_inputs: &[FunctionInput], - signature_inputs: &[FunctionInput], + public_key_x_inputs: &[FunctionInput; 32], + public_key_y_inputs: &[FunctionInput; 32], + signature_inputs: &[FunctionInput; 64], hashed_message_inputs: &[FunctionInput], output: Witness, ) -> Result<(), OpcodeResolutionError> { let hashed_message = to_u8_vec(initial_witness, hashed_message_inputs)?; - let pub_key_x: [u8; 32] = - to_u8_vec(initial_witness, public_key_x_inputs)?.try_into().map_err(|_| { - OpcodeResolutionError::BlackBoxFunctionFailed( - acir::BlackBoxFunc::EcdsaSecp256r1, - format!("expected pubkey_x size 32 but received {}", public_key_x_inputs.len()), - ) - })?; - - let pub_key_y: [u8; 32] = - to_u8_vec(initial_witness, public_key_y_inputs)?.try_into().map_err(|_| { - OpcodeResolutionError::BlackBoxFunctionFailed( - acir::BlackBoxFunc::EcdsaSecp256r1, - format!("expected pubkey_y size 32 but received {}", public_key_y_inputs.len()), - ) - })?; - - let signature: [u8; 64] = - to_u8_vec(initial_witness, signature_inputs)?.try_into().map_err(|_| { - OpcodeResolutionError::BlackBoxFunctionFailed( - acir::BlackBoxFunc::EcdsaSecp256r1, - format!("expected signature size 64 but received {}", signature_inputs.len()), - ) - })?; + let pub_key_x: [u8; 32] = to_u8_array(initial_witness, public_key_x_inputs)?; + let pub_key_y: [u8; 32] = to_u8_array(initial_witness, public_key_y_inputs)?; + let signature: [u8; 64] = to_u8_array(initial_witness, signature_inputs)?; let is_valid = ecdsa_secp256r1_verify(&hashed_message, &pub_key_x, &pub_key_y, &signature)?; - insert_value(&output, FieldElement::from(is_valid), initial_witness)?; - Ok(()) + insert_value(&output, FieldElement::from(is_valid), initial_witness) } diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/mod.rs index 0e28a63ff681..bd223ecd0c97 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/mod.rs @@ -2,6 +2,21 @@ use acir::{circuit::opcodes::FunctionInput, native_types::WitnessMap}; use crate::pwg::{witness_to_value, OpcodeResolutionError}; +fn to_u8_array( + initial_witness: &WitnessMap, + inputs: &[FunctionInput; N], +) -> Result<[u8; N], OpcodeResolutionError> { + let mut result = [0; N]; + for (it, input) in result.iter_mut().zip(inputs) { + let witness_value_bytes = witness_to_value(initial_witness, input.witness)?.to_be_bytes(); + let byte = witness_value_bytes + .last() + .expect("Field element must be represented by non-zero amount of bytes"); + *it = *byte; + } + Ok(result) +} + fn to_u8_vec( initial_witness: &WitnessMap, inputs: &[FunctionInput], diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs index 7f5381cee91f..3d0216fa2173 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs @@ -1,4 +1,4 @@ -use super::to_u8_vec; +use super::{to_u8_array, to_u8_vec}; use crate::{ pwg::{insert_value, witness_to_value, OpcodeResolutionError}, BlackBoxFunctionSolver, @@ -15,15 +15,14 @@ pub(crate) fn schnorr_verify( initial_witness: &mut WitnessMap, public_key_x: FunctionInput, public_key_y: FunctionInput, - signature: &[FunctionInput], + signature: &[FunctionInput; 64], message: &[FunctionInput], output: Witness, ) -> Result<(), OpcodeResolutionError> { let public_key_x: &FieldElement = witness_to_value(initial_witness, public_key_x.witness)?; let public_key_y: &FieldElement = witness_to_value(initial_witness, public_key_y.witness)?; - let signature = to_u8_vec(initial_witness, signature)?; - + let signature = to_u8_array(initial_witness, signature)?; let message = to_u8_vec(initial_witness, message)?; let valid_signature = diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs index 81e752d5656e..67faf7f50073 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use acir::{ - brillig::{ForeignCallParam, ForeignCallResult}, + brillig::{ForeignCallParam, ForeignCallResult, Opcode as BrilligOpcode}, circuit::{ brillig::{Brillig, BrilligInputs, BrilligOutputs}, opcodes::BlockId, @@ -11,7 +11,7 @@ use acir::{ FieldElement, }; use acvm_blackbox_solver::BlackBoxFunctionSolver; -use brillig_vm::{MemoryValue, VMStatus, VM}; +use brillig_vm::{FailureReason, MemoryValue, VMStatus, VM}; use crate::{pwg::OpcodeNotSolvable, OpcodeResolutionError}; @@ -46,9 +46,9 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { /// Assigns the zero value to all outputs of the given [`Brillig`] bytecode. pub(super) fn zero_out_brillig_outputs( initial_witness: &mut WitnessMap, - brillig: &Brillig, + outputs: &[BrilligOutputs], ) -> Result<(), OpcodeResolutionError> { - for output in &brillig.outputs { + for output in outputs { match output { BrilligOutputs::Simple(witness) => { insert_value(witness, FieldElement::zero(), initial_witness)?; @@ -63,6 +63,7 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { Ok(()) } + // TODO: Delete this old method once `Brillig` is deleted /// Constructs a solver for a Brillig block given the bytecode and initial /// witness. pub(crate) fn new( @@ -72,13 +73,45 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { bb_solver: &'b B, acir_index: usize, ) -> Result { + let vm = Self::setup_brillig_vm( + initial_witness, + memory, + &brillig.inputs, + &brillig.bytecode, + bb_solver, + )?; + Ok(Self { vm, acir_index }) + } + + /// Constructs a solver for a Brillig block given the bytecode and initial + /// witness. + pub(crate) fn new_call( + initial_witness: &WitnessMap, + memory: &HashMap, + inputs: &'b [BrilligInputs], + brillig_bytecode: &'b [BrilligOpcode], + bb_solver: &'b B, + acir_index: usize, + ) -> Result { + let vm = + Self::setup_brillig_vm(initial_witness, memory, inputs, brillig_bytecode, bb_solver)?; + Ok(Self { vm, acir_index }) + } + + fn setup_brillig_vm( + initial_witness: &WitnessMap, + memory: &HashMap, + inputs: &[BrilligInputs], + brillig_bytecode: &'b [BrilligOpcode], + bb_solver: &'b B, + ) -> Result, OpcodeResolutionError> { // Set input values let mut calldata: Vec = Vec::new(); // Each input represents an expression or array of expressions to evaluate. // Iterate over each input and evaluate the expression(s) associated with it. // Push the results into memory. // If a certain expression is not solvable, we stall the ACVM and do not proceed with Brillig VM execution. - for input in &brillig.inputs { + for input in inputs { match input { BrilligInputs::Single(expr) => match get_value(expr, initial_witness) { Ok(value) => calldata.push(value), @@ -118,8 +151,8 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { // Instantiate a Brillig VM given the solved calldata // along with the Brillig bytecode. - let vm = VM::new(calldata, &brillig.bytecode, vec![], bb_solver); - Ok(Self { vm, acir_index }) + let vm = VM::new(calldata, brillig_bytecode, vec![], bb_solver); + Ok(vm) } pub fn get_memory(&self) -> &[MemoryValue] { @@ -159,7 +192,31 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { match vm_status { VMStatus::Finished { .. } => Ok(BrilligSolverStatus::Finished), VMStatus::InProgress => Ok(BrilligSolverStatus::InProgress), - VMStatus::Failure { message, call_stack } => { + VMStatus::Failure { reason, call_stack } => { + let message = match reason { + FailureReason::RuntimeError { message } => Some(message), + FailureReason::Trap { revert_data_offset, revert_data_size } => { + // Since noir can only revert with strings currently, we can parse return data as a string + if revert_data_size == 0 { + None + } else { + let memory = self.vm.get_memory(); + let bytes = memory + [revert_data_offset..(revert_data_offset + revert_data_size)] + .iter() + .map(|memory_value| { + memory_value + .try_into() + .expect("Assert message character is not a byte") + }) + .collect(); + Some( + String::from_utf8(bytes) + .expect("Assert message is not valid UTF-8"), + ) + } + } + }; Err(OpcodeResolutionError::BrilligFunctionFailed { message, call_stack: call_stack @@ -180,13 +237,13 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { pub(crate) fn finalize( self, witness: &mut WitnessMap, - brillig: &Brillig, + outputs: &[BrilligOutputs], ) -> Result<(), OpcodeResolutionError> { // Finish the Brillig execution by writing the outputs to the witness map let vm_status = self.vm.get_status(); match vm_status { VMStatus::Finished { return_data_offset, return_data_size } => { - self.write_brillig_outputs(witness, return_data_offset, return_data_size, brillig)?; + self.write_brillig_outputs(witness, return_data_offset, return_data_size, outputs)?; Ok(()) } _ => panic!("Brillig VM has not completed execution"), @@ -198,12 +255,12 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { witness_map: &mut WitnessMap, return_data_offset: usize, return_data_size: usize, - brillig: &Brillig, + outputs: &[BrilligOutputs], ) -> Result<(), OpcodeResolutionError> { // Write VM execution results into the witness map let memory = self.vm.get_memory(); let mut current_ret_data_idx = return_data_offset; - for output in brillig.outputs.iter() { + for output in outputs.iter() { match output { BrilligOutputs::Simple(witness) => { insert_value(witness, memory[current_ret_data_idx].to_field(), witness_map)?; @@ -218,6 +275,7 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { } } } + assert!( current_ret_data_idx == return_data_offset + return_data_size, "Brillig VM did not write the expected number of return values" diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs index bb98eda2689b..652e173867ab 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs @@ -4,14 +4,14 @@ use std::collections::HashMap; use acir::{ brillig::ForeignCallResult, - circuit::{opcodes::BlockId, Opcode, OpcodeLocation}, + circuit::{brillig::BrilligBytecode, opcodes::BlockId, Opcode, OpcodeLocation}, native_types::{Expression, Witness, WitnessMap}, BlackBoxFunc, FieldElement, }; use acvm_blackbox_solver::BlackBoxResolutionError; use self::{ - arithmetic::ExpressionSolver, blackbox::bigint::BigIntSolver, directives::solve_directives, + arithmetic::ExpressionSolver, blackbox::bigint::AcvmBigIntSolver, directives::solve_directives, memory_op::MemoryOpSolver, }; use crate::BlackBoxFunctionSolver; @@ -122,8 +122,8 @@ pub enum OpcodeResolutionError { IndexOutOfBounds { opcode_location: ErrorLocation, index: u32, array_size: u32 }, #[error("Failed to solve blackbox function: {0}, reason: {1}")] BlackBoxFunctionFailed(BlackBoxFunc, String), - #[error("Failed to solve brillig function, reason: {message}")] - BrilligFunctionFailed { message: String, call_stack: Vec }, + #[error("Failed to solve brillig function{}", .message.as_ref().map(|m| format!(", reason: {}", m)).unwrap_or_default())] + BrilligFunctionFailed { message: Option, call_stack: Vec }, #[error("Attempted to call `main` with a `Call` opcode")] AcirMainCallAttempted { opcode_location: ErrorLocation }, #[error("{results_size:?} result values were provided for {outputs_size:?} call output witnesses, most likely due to bad ACIR codegen")] @@ -148,7 +148,7 @@ pub struct ACVM<'a, B: BlackBoxFunctionSolver> { /// Stores the solver for memory operations acting on blocks of memory disambiguated by [block][`BlockId`]. block_solvers: HashMap, - bigint_solver: BigIntSolver, + bigint_solver: AcvmBigIntSolver, /// A list of opcodes which are to be executed by the ACVM. opcodes: &'a [Opcode], @@ -165,22 +165,31 @@ pub struct ACVM<'a, B: BlackBoxFunctionSolver> { /// Represents the outputs of all ACIR calls during an ACVM process /// List is appended onto by the caller upon reaching a [ACVMStatus::RequiresAcirCall] acir_call_results: Vec>, + + // Each unconstrained function referenced in the program + unconstrained_functions: &'a [BrilligBytecode], } impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { - pub fn new(backend: &'a B, opcodes: &'a [Opcode], initial_witness: WitnessMap) -> Self { + pub fn new( + backend: &'a B, + opcodes: &'a [Opcode], + initial_witness: WitnessMap, + unconstrained_functions: &'a [BrilligBytecode], + ) -> Self { let status = if opcodes.is_empty() { ACVMStatus::Solved } else { ACVMStatus::InProgress }; ACVM { status, backend, block_solvers: HashMap::default(), - bigint_solver: BigIntSolver::default(), + bigint_solver: AcvmBigIntSolver::default(), opcodes, instruction_pointer: 0, witness_map: initial_witness, brillig_solver: None, acir_call_counter: 0, acir_call_results: Vec::default(), + unconstrained_functions, } } @@ -324,6 +333,10 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { Ok(Some(foreign_call)) => return self.wait_for_foreign_call(foreign_call), res => res.map(|_| ()), }, + Opcode::BrilligCall { .. } => match self.solve_brillig_call_opcode() { + Ok(Some(foreign_call)) => return self.wait_for_foreign_call(foreign_call), + res => res.map(|_| ()), + }, Opcode::Call { .. } => match self.solve_call_opcode() { Ok(Some(input_values)) => return self.wait_for_acir_call(input_values), res => res.map(|_| ()), @@ -378,7 +391,8 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { let witness = &mut self.witness_map; if is_predicate_false(witness, &brillig.predicate)? { - return BrilligSolver::::zero_out_brillig_outputs(witness, brillig).map(|_| None); + return BrilligSolver::::zero_out_brillig_outputs(witness, &brillig.outputs) + .map(|_| None); } // If we're resuming execution after resolving a foreign call then @@ -404,7 +418,51 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { } BrilligSolverStatus::Finished => { // Write execution outputs - solver.finalize(witness, brillig)?; + solver.finalize(witness, &brillig.outputs)?; + Ok(None) + } + } + } + + fn solve_brillig_call_opcode( + &mut self, + ) -> Result, OpcodeResolutionError> { + let Opcode::BrilligCall { id, inputs, outputs, predicate } = + &self.opcodes[self.instruction_pointer] + else { + unreachable!("Not executing a Brillig opcode"); + }; + + let witness = &mut self.witness_map; + if is_predicate_false(witness, predicate)? { + return BrilligSolver::::zero_out_brillig_outputs(witness, outputs).map(|_| None); + } + + // If we're resuming execution after resolving a foreign call then + // there will be a cached `BrilligSolver` to avoid recomputation. + let mut solver: BrilligSolver<'_, B> = match self.brillig_solver.take() { + Some(solver) => solver, + None => BrilligSolver::new_call( + witness, + &self.block_solvers, + inputs, + &self.unconstrained_functions[*id as usize].bytecode, + self.backend, + self.instruction_pointer, + )?, + }; + match solver.solve()? { + BrilligSolverStatus::ForeignCallWait(foreign_call) => { + // Cache the current state of the solver + self.brillig_solver = Some(solver); + Ok(Some(foreign_call)) + } + BrilligSolverStatus::InProgress => { + unreachable!("Brillig solver still in progress") + } + BrilligSolverStatus::Finished => { + // Write execution outputs + solver.finalize(witness, outputs)?; Ok(None) } } @@ -422,7 +480,8 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { }; if should_skip { - let resolution = BrilligSolver::::zero_out_brillig_outputs(witness, brillig); + let resolution = + BrilligSolver::::zero_out_brillig_outputs(witness, &brillig.outputs); return StepResult::Status(self.handle_opcode_resolution(resolution)); } diff --git a/noir/noir-repo/acvm-repo/acvm/tests/solver.rs b/noir/noir-repo/acvm-repo/acvm/tests/solver.rs index a708db5b0300..f009e2c05b82 100644 --- a/noir/noir-repo/acvm-repo/acvm/tests/solver.rs +++ b/noir/noir-repo/acvm-repo/acvm/tests/solver.rs @@ -104,8 +104,9 @@ fn inversion_brillig_oracle_equivalence() { (Witness(2), FieldElement::from(3u128)), ]) .into(); - - let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, witness_assignments); + let unconstrained_functions = vec![]; + let mut acvm = + ACVM::new(&StubbedBlackBoxSolver, &opcodes, witness_assignments, &unconstrained_functions); // use the partial witness generation solver with our acir program let solver_status = acvm.solve(); @@ -241,8 +242,9 @@ fn double_inversion_brillig_oracle() { (Witness(9), FieldElement::from(10u128)), ]) .into(); - - let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, witness_assignments); + let unconstrained_functions = vec![]; + let mut acvm = + ACVM::new(&StubbedBlackBoxSolver, &opcodes, witness_assignments, &unconstrained_functions); // use the partial witness generation solver with our acir program let solver_status = acvm.solve(); @@ -370,8 +372,9 @@ fn oracle_dependent_execution() { let witness_assignments = BTreeMap::from([(w_x, FieldElement::from(2u128)), (w_y, FieldElement::from(2u128))]).into(); - - let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, witness_assignments); + let unconstrained_functions = vec![]; + let mut acvm = + ACVM::new(&StubbedBlackBoxSolver, &opcodes, witness_assignments, &unconstrained_functions); // use the partial witness generation solver with our acir program let solver_status = acvm.solve(); @@ -474,8 +477,9 @@ fn brillig_oracle_predicate() { (Witness(2), FieldElement::from(3u128)), ]) .into(); - - let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, witness_assignments); + let unconstrained_functions = vec![]; + let mut acvm = + ACVM::new(&StubbedBlackBoxSolver, &opcodes, witness_assignments, &unconstrained_functions); let solver_status = acvm.solve(); assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); @@ -509,7 +513,8 @@ fn unsatisfied_opcode_resolved() { values.insert(d, FieldElement::from(2_i128)); let opcodes = vec![Opcode::AssertZero(opcode_a)]; - let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, values); + let unconstrained_functions = vec![]; + let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, values, &unconstrained_functions); let solver_status = acvm.solve(); assert_eq!( solver_status, @@ -549,7 +554,7 @@ fn unsatisfied_opcode_resolved_brillig() { let jmp_if_opcode = BrilligOpcode::JumpIf { condition: MemoryAddress::from(2), location: location_of_stop }; - let trap_opcode = BrilligOpcode::Trap; + let trap_opcode = BrilligOpcode::Trap { revert_data_offset: 0, revert_data_size: 0 }; let stop_opcode = BrilligOpcode::Stop { return_data_offset: 0, return_data_size: 0 }; let brillig_opcode = Opcode::Brillig(Brillig { @@ -591,13 +596,13 @@ fn unsatisfied_opcode_resolved_brillig() { values.insert(w_result, FieldElement::from(0_i128)); let opcodes = vec![brillig_opcode, Opcode::AssertZero(opcode_a)]; - - let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, values); + let unconstrained_functions = vec![]; + let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, values, &unconstrained_functions); let solver_status = acvm.solve(); assert_eq!( solver_status, ACVMStatus::Failure(OpcodeResolutionError::BrilligFunctionFailed { - message: "explicit trap hit in brillig".to_string(), + message: None, call_stack: vec![OpcodeLocation::Brillig { acir_index: 0, brillig_index: 3 }] }), "The first opcode is not satisfiable, expected an error indicating this" @@ -635,8 +640,9 @@ fn memory_operations() { }); let opcodes = vec![init, read_op, expression]; - - let mut acvm = ACVM::new(&StubbedBlackBoxSolver, &opcodes, initial_witness); + let unconstrained_functions = vec![]; + let mut acvm = + ACVM::new(&StubbedBlackBoxSolver, &opcodes, initial_witness, &unconstrained_functions); let solver_status = acvm.solve(); assert_eq!(solver_status, ACVMStatus::Solved); let witness_map = acvm.finalize(); diff --git a/noir/noir-repo/acvm-repo/acvm_js/src/execute.rs b/noir/noir-repo/acvm-repo/acvm_js/src/execute.rs index c97b8ea1a665..2fab684467e5 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/src/execute.rs +++ b/noir/noir-repo/acvm-repo/acvm_js/src/execute.rs @@ -1,5 +1,6 @@ use std::{future::Future, pin::Pin}; +use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::BlackBoxFunctionSolver; use acvm::{ acir::circuit::{Circuit, Program}, @@ -181,7 +182,12 @@ async fn execute_program_with_native_program_and_return( initial_witness: JsWitnessMap, foreign_call_executor: &ForeignCallHandler, ) -> Result { - let executor = ProgramExecutor::new(&program.functions, &solver.0, foreign_call_executor); + let executor = ProgramExecutor::new( + &program.functions, + &program.unconstrained_functions, + &solver.0, + foreign_call_executor, + ); let witness_stack = executor.execute(initial_witness.into()).await?; Ok(witness_stack) @@ -190,6 +196,8 @@ async fn execute_program_with_native_program_and_return( struct ProgramExecutor<'a, B: BlackBoxFunctionSolver> { functions: &'a [Circuit], + unconstrained_functions: &'a [BrilligBytecode], + blackbox_solver: &'a B, foreign_call_handler: &'a ForeignCallHandler, @@ -198,10 +206,16 @@ struct ProgramExecutor<'a, B: BlackBoxFunctionSolver> { impl<'a, B: BlackBoxFunctionSolver> ProgramExecutor<'a, B> { fn new( functions: &'a [Circuit], + unconstrained_functions: &'a [BrilligBytecode], blackbox_solver: &'a B, foreign_call_handler: &'a ForeignCallHandler, ) -> Self { - ProgramExecutor { functions, blackbox_solver, foreign_call_handler } + ProgramExecutor { + functions, + unconstrained_functions, + blackbox_solver, + foreign_call_handler, + } } async fn execute(&self, initial_witness: WitnessMap) -> Result { @@ -220,7 +234,12 @@ impl<'a, B: BlackBoxFunctionSolver> ProgramExecutor<'a, B> { witness_stack: &'a mut WitnessStack, ) -> Pin> + 'a>> { Box::pin(async { - let mut acvm = ACVM::new(self.blackbox_solver, &circuit.opcodes, initial_witness); + let mut acvm = ACVM::new( + self.blackbox_solver, + &circuit.opcodes, + initial_witness, + self.unconstrained_functions, + ); loop { let solver_status = acvm.solve(); @@ -231,7 +250,7 @@ impl<'a, B: BlackBoxFunctionSolver> ProgramExecutor<'a, B> { unreachable!("Execution should not stop while in `InProgress` state.") } ACVMStatus::Failure(error) => { - let (assert_message, call_stack) = match &error { + let (assert_message, call_stack): (Option<&str>, _) = match &error { OpcodeResolutionError::UnsatisfiedConstrain { opcode_location: ErrorLocation::Resolved(opcode_location), } @@ -242,12 +261,16 @@ impl<'a, B: BlackBoxFunctionSolver> ProgramExecutor<'a, B> { circuit.get_assert_message(*opcode_location), Some(vec![*opcode_location]), ), - OpcodeResolutionError::BrilligFunctionFailed { call_stack, .. } => { + OpcodeResolutionError::BrilligFunctionFailed { + call_stack, + message, + } => { + let revert_message = message.as_ref().map(String::as_str); let failing_opcode = call_stack .last() .expect("Brillig error call stacks cannot be empty"); ( - circuit.get_assert_message(*failing_opcode), + revert_message.or(circuit.get_assert_message(*failing_opcode)), Some(call_stack.clone()), ) } diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/addition.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/addition.ts index b56a42868787..820a415acf39 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/addition.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/addition.ts @@ -2,11 +2,11 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `addition_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, 173, 144, 75, 14, 128, 32, 12, 68, 249, 120, 160, 150, 182, 208, 238, 188, 138, 68, - 184, 255, 17, 212, 200, 130, 196, 165, 188, 164, 153, 174, 94, 38, 227, 221, 203, 118, 159, 119, 95, 226, 200, 125, - 36, 252, 3, 253, 66, 87, 152, 92, 4, 153, 185, 149, 212, 144, 240, 128, 100, 85, 5, 88, 106, 86, 84, 20, 149, 51, 41, - 81, 83, 214, 98, 213, 10, 24, 50, 53, 236, 98, 212, 135, 44, 174, 235, 5, 143, 35, 12, 151, 159, 126, 55, 109, 28, - 231, 145, 47, 245, 105, 191, 143, 133, 1, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 65, 14, 128, 32, 12, 4, 65, 124, 80, 75, 91, 104, 111, 126, 69, 34, 252, + 255, 9, 106, 228, 64, 162, 55, 153, 164, 217, 158, 38, 155, 245, 238, 97, 189, 206, 187, 55, 161, 231, 214, 19, 254, + 129, 126, 162, 107, 25, 92, 4, 137, 185, 230, 88, 145, 112, 135, 104, 69, 5, 88, 74, 82, 84, 20, 149, 35, 42, 81, 85, + 214, 108, 197, 50, 24, 50, 85, 108, 98, 212, 186, 44, 204, 235, 5, 183, 99, 233, 46, 63, 252, 110, 216, 56, 184, 15, + 78, 146, 74, 173, 20, 141, 1, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts index e074cf1ad384..722bae8e015b 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts @@ -2,13 +2,13 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `complex_brillig_foreign_call` 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, 84, 93, 10, 131, 48, 12, 78, 218, 233, 100, 111, 187, 193, 96, 59, 64, 231, 9, - 188, 139, 248, 166, 232, 163, 167, 23, 11, 126, 197, 24, 250, 34, 86, 208, 64, 72, 218, 252, 125, 36, 105, 153, 22, - 42, 60, 51, 116, 235, 217, 64, 103, 156, 37, 5, 191, 10, 210, 29, 163, 63, 167, 203, 229, 206, 194, 104, 110, 128, - 209, 158, 128, 49, 236, 195, 69, 231, 157, 114, 46, 73, 251, 103, 35, 239, 231, 225, 57, 243, 156, 227, 252, 132, 44, - 112, 79, 176, 125, 84, 223, 73, 248, 145, 152, 69, 149, 4, 107, 233, 114, 90, 119, 145, 85, 237, 151, 192, 89, 247, - 221, 208, 54, 163, 85, 174, 26, 234, 87, 232, 63, 101, 103, 21, 55, 169, 216, 73, 72, 249, 5, 197, 234, 132, 123, 179, - 35, 247, 155, 214, 246, 102, 20, 73, 204, 72, 168, 123, 191, 161, 25, 66, 136, 159, 187, 53, 5, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 84, 75, 10, 132, 48, 12, 77, 218, 209, 145, 217, 205, 13, 6, 198, 3, 84, 79, + 224, 93, 196, 157, 162, 75, 79, 47, 22, 124, 197, 16, 186, 17, 43, 104, 32, 36, 109, 126, 143, 36, 45, 211, 70, 133, + 103, 134, 110, 61, 27, 232, 140, 179, 164, 224, 215, 64, 186, 115, 84, 113, 186, 92, 238, 42, 140, 230, 1, 24, 237, 5, + 24, 195, 62, 220, 116, 222, 41, 231, 146, 180, 127, 54, 242, 126, 94, 158, 51, 207, 57, 206, 111, 200, 2, 247, 4, 219, + 79, 245, 157, 132, 31, 137, 89, 52, 73, 176, 214, 46, 167, 125, 23, 89, 213, 254, 8, 156, 237, 56, 76, 125, 55, 91, + 229, 170, 161, 254, 133, 94, 42, 59, 171, 184, 69, 197, 46, 66, 202, 47, 40, 86, 39, 220, 155, 3, 185, 191, 180, 183, + 55, 163, 72, 98, 70, 66, 221, 251, 40, 173, 255, 35, 68, 62, 61, 5, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/fixed_base_scalar_mul.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/fixed_base_scalar_mul.ts index 5aef521f2313..97b5041121a8 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/fixed_base_scalar_mul.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/fixed_base_scalar_mul.ts @@ -1,8 +1,8 @@ // See `fixed_base_scalar_mul_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, 77, 138, 81, 10, 0, 48, 8, 66, 87, 219, 190, 118, 233, 29, 61, 43, 3, 5, 121, 34, - 207, 86, 231, 162, 198, 157, 124, 228, 71, 157, 220, 232, 161, 227, 226, 206, 214, 95, 221, 74, 0, 116, 58, 13, 182, - 105, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 138, 81, 10, 0, 48, 8, 66, 87, 219, 190, 118, 233, 29, 61, 35, 3, 19, 228, 137, + 60, 91, 149, 139, 26, 119, 242, 145, 31, 117, 114, 163, 135, 142, 139, 219, 91, 127, 117, 71, 2, 117, 84, 50, 98, 113, + 0, 0, 0, ]); export const initialWitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts index eb14cb2e9f1b..0e3d77f62a9e 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/foreign_call.ts @@ -2,10 +2,10 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `simple_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 61, 10, 192, 48, 8, 133, 53, 133, 82, 186, 245, 38, 233, 13, 122, 153, - 14, 93, 58, 132, 144, 227, 135, 252, 41, 56, 36, 46, 201, 7, 162, 168, 200, 123, 34, 52, 142, 28, 72, 245, 38, 106, 9, - 247, 30, 202, 118, 142, 27, 215, 221, 178, 82, 175, 33, 15, 133, 189, 163, 159, 57, 197, 252, 251, 195, 235, 188, 230, - 186, 16, 65, 255, 12, 239, 92, 131, 89, 149, 198, 77, 3, 10, 9, 119, 8, 198, 242, 152, 1, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 61, 10, 192, 32, 12, 133, 19, 11, 165, 116, 235, 77, 236, 13, 122, 153, + 14, 93, 58, 136, 120, 124, 241, 47, 129, 12, 42, 130, 126, 16, 18, 146, 16, 222, 11, 66, 225, 136, 129, 84, 111, 162, + 150, 112, 239, 161, 172, 231, 184, 113, 221, 45, 45, 245, 42, 242, 144, 216, 43, 250, 153, 83, 204, 191, 223, 189, + 198, 246, 92, 39, 60, 244, 63, 195, 59, 87, 99, 150, 165, 113, 83, 193, 0, 1, 19, 247, 29, 5, 160, 1, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000005'], diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/memory_op.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/memory_op.ts index 1d0e06b3c8a8..a69ae4432591 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/memory_op.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/memory_op.ts @@ -1,9 +1,9 @@ // See `memory_op_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, 81, 201, 13, 0, 32, 8, 147, 195, 125, 112, 3, 247, 159, 74, 141, 60, 106, 226, - 79, 120, 216, 132, 180, 124, 154, 82, 168, 108, 212, 57, 2, 122, 129, 157, 201, 181, 150, 59, 186, 179, 189, 161, 101, - 251, 82, 176, 175, 196, 121, 89, 118, 185, 246, 91, 185, 26, 125, 187, 64, 80, 134, 29, 195, 31, 79, 24, 2, 250, 167, - 252, 27, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 81, 57, 14, 0, 32, 8, 147, 195, 255, 224, 15, 252, 255, 171, 212, 200, 208, + 129, 77, 24, 108, 66, 90, 150, 166, 20, 106, 23, 125, 143, 128, 62, 96, 103, 114, 173, 45, 198, 116, 182, 55, 140, + 106, 95, 74, 246, 149, 60, 47, 171, 46, 215, 126, 43, 87, 179, 111, 23, 8, 202, 176, 99, 248, 240, 9, 11, 137, 33, + 212, 110, 35, 3, 0, 0, ]); export const initialWitnessMap = new Map([ 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 1b745ab6a79a..4b73d01bb011 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 205, 146, 65, 10, 3, 33, 12, 69, 163, 46, 230, 58, 137, 209, 49, 238, 122, 149, 74, + 157, 251, 31, 161, 83, 154, 161, 86, 132, 89, 212, 194, 124, 248, 24, 36, 132, 228, 241, 29, 188, 229, 212, 47, 45, + 187, 205, 110, 11, 31, 25, 53, 28, 255, 103, 77, 14, 58, 29, 141, 55, 125, 241, 55, 145, 109, 102, 49, 174, 33, 212, + 228, 43, 49, 221, 209, 231, 34, 17, 67, 44, 171, 144, 80, 148, 248, 240, 194, 92, 37, 72, 202, 37, 39, 204, 20, 184, + 210, 22, 51, 111, 58, 204, 205, 219, 11, 161, 129, 208, 214, 6, 6, 114, 29, 193, 127, 193, 130, 137, 176, 236, 188, + 189, 252, 162, 183, 218, 230, 238, 97, 138, 250, 152, 245, 245, 87, 220, 12, 140, 113, 95, 153, 170, 129, 185, 17, 60, + 3, 54, 212, 19, 104, 145, 195, 151, 14, 4, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/pedersen.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/pedersen.ts index 00d207053d89..e8ddc893d879 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/pedersen.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/pedersen.ts @@ -1,7 +1,7 @@ // See `pedersen_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, 93, 74, 7, 6, 0, 0, 8, 108, 209, 255, 63, 156, 54, 233, 56, 55, 17, 26, 18, 196, - 241, 169, 250, 178, 141, 167, 32, 159, 254, 234, 238, 255, 87, 112, 52, 63, 63, 101, 105, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 74, 9, 10, 0, 0, 4, 115, 149, 255, 127, 88, 8, 133, 213, 218, 137, 80, 144, 32, + 182, 79, 213, 151, 173, 61, 5, 121, 245, 91, 103, 255, 191, 3, 7, 16, 26, 112, 158, 113, 0, 0, 0, ]); export const initialWitnessMap = new Map([[1, '0x0000000000000000000000000000000000000000000000000000000000000001']]); diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/schnorr_verify.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/schnorr_verify.ts index 14c32c615c81..a207aa12b2c1 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/schnorr_verify.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/schnorr_verify.ts @@ -1,17 +1,17 @@ // See `schnorr_verify_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, 77, 210, 7, 78, 2, 1, 20, 69, 81, 236, 189, 247, 222, 123, 239, 93, 177, 33, 34, - 238, 194, 253, 47, 193, 200, 147, 67, 194, 36, 147, 163, 33, 33, 228, 191, 219, 82, 168, 63, 63, 181, 183, 197, 223, - 177, 147, 191, 181, 183, 149, 69, 159, 183, 213, 222, 238, 218, 219, 206, 14, 118, 178, 139, 141, 183, 135, 189, 236, - 99, 63, 7, 56, 200, 33, 14, 115, 132, 163, 28, 227, 56, 39, 56, 201, 41, 78, 115, 134, 179, 156, 227, 60, 23, 184, - 200, 37, 46, 115, 133, 171, 92, 227, 58, 55, 184, 201, 45, 110, 115, 135, 187, 220, 227, 62, 15, 120, 200, 35, 30, - 243, 132, 167, 60, 227, 57, 47, 120, 201, 43, 94, 243, 134, 183, 188, 227, 61, 31, 248, 200, 39, 22, 249, 204, 151, - 166, 29, 243, 188, 250, 255, 141, 239, 44, 241, 131, 101, 126, 178, 194, 47, 86, 249, 237, 123, 171, 76, 127, 105, 47, - 189, 165, 181, 116, 150, 198, 26, 125, 245, 248, 45, 233, 41, 45, 165, 163, 52, 148, 126, 210, 78, 186, 73, 51, 233, - 37, 173, 164, 147, 52, 146, 62, 210, 70, 186, 72, 19, 233, 33, 45, 164, 131, 52, 144, 253, 151, 11, 245, 221, 179, - 121, 246, 206, 214, 217, 57, 27, 103, 223, 109, 187, 238, 218, 115, 223, 142, 135, 246, 59, 182, 219, 169, 189, 206, - 237, 116, 105, 159, 107, 187, 220, 218, 227, 222, 14, 143, 238, 95, 116, 247, 23, 119, 126, 115, 223, 146, 187, 150, - 221, 179, 226, 142, 141, 155, 53, 238, 86, 104, 186, 231, 255, 243, 7, 100, 141, 232, 192, 233, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 210, 85, 78, 67, 81, 24, 133, 209, 226, 238, 238, 238, 238, 238, 165, 148, 82, + 102, 193, 252, 135, 64, 232, 78, 87, 147, 114, 147, 147, 5, 47, 132, 252, 251, 107, 41, 212, 191, 159, 218, 107, 241, + 115, 236, 228, 111, 237, 181, 178, 173, 246, 186, 107, 175, 157, 29, 236, 100, 23, 27, 175, 135, 189, 236, 99, 63, 7, + 56, 200, 33, 14, 115, 132, 163, 28, 227, 56, 39, 56, 201, 41, 78, 115, 134, 179, 156, 227, 60, 23, 184, 200, 37, 46, + 115, 133, 171, 92, 227, 58, 55, 184, 201, 45, 110, 115, 135, 187, 220, 227, 62, 15, 120, 200, 35, 30, 243, 132, 167, + 60, 227, 57, 47, 120, 201, 43, 94, 243, 134, 183, 188, 227, 61, 31, 248, 200, 39, 62, 243, 133, 175, 77, 59, 230, 123, + 243, 123, 145, 239, 44, 241, 131, 101, 126, 178, 194, 47, 86, 249, 237, 239, 86, 153, 238, 210, 92, 122, 75, 107, 233, + 44, 141, 53, 250, 234, 241, 191, 164, 167, 180, 148, 142, 210, 80, 250, 73, 59, 233, 38, 205, 164, 151, 180, 146, 78, + 210, 72, 250, 72, 27, 233, 34, 77, 164, 135, 180, 144, 14, 210, 64, 246, 95, 46, 212, 119, 207, 230, 217, 59, 91, 103, + 231, 108, 156, 125, 183, 237, 186, 107, 207, 125, 59, 30, 218, 239, 216, 110, 167, 246, 58, 183, 211, 165, 125, 174, + 237, 114, 107, 143, 123, 59, 60, 186, 255, 179, 187, 191, 186, 115, 209, 125, 75, 238, 90, 118, 207, 138, 59, 54, 110, + 214, 184, 91, 161, 233, 158, 255, 190, 63, 165, 188, 93, 151, 233, 3, 0, 0, ]); export const initialWitnessMap = new Map([ diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/Cargo.toml b/noir/noir-repo/acvm-repo/blackbox_solver/Cargo.toml index d093b24a1292..1d6629c82238 100644 --- a/noir/noir-repo/acvm-repo/blackbox_solver/Cargo.toml +++ b/noir/noir-repo/acvm-repo/blackbox_solver/Cargo.toml @@ -15,6 +15,7 @@ repository.workspace = true [dependencies] acir.workspace = true thiserror.workspace = true +num-bigint = "0.4" blake2 = "0.10.6" blake3 = "1.5.0" diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/src/bigint.rs b/noir/noir-repo/acvm-repo/blackbox_solver/src/bigint.rs new file mode 100644 index 000000000000..5b19f03a2381 --- /dev/null +++ b/noir/noir-repo/acvm-repo/blackbox_solver/src/bigint.rs @@ -0,0 +1,99 @@ +use std::collections::HashMap; + +use acir::BlackBoxFunc; + +use num_bigint::BigUint; + +use crate::BlackBoxResolutionError; + +/// Resolve BigInt opcodes by storing BigInt values (and their moduli) by their ID in a HashMap: +/// - When it encounters a bigint operation opcode, it performs the operation on the stored values +/// and store the result using the provided ID. +/// - When it gets a to_bytes opcode, it simply looks up the value and resolves the output witness accordingly. +#[derive(Default, Debug, Clone, PartialEq, Eq)] + +pub struct BigIntSolver { + bigint_id_to_value: HashMap, + bigint_id_to_modulus: HashMap, +} + +impl BigIntSolver { + pub(crate) fn get_bigint( + &self, + id: u32, + func: BlackBoxFunc, + ) -> Result { + self.bigint_id_to_value + .get(&id) + .ok_or(BlackBoxResolutionError::Failed( + func, + format!("could not find bigint of id {id}"), + )) + .cloned() + } + + pub(crate) fn get_modulus( + &self, + id: u32, + func: BlackBoxFunc, + ) -> Result { + self.bigint_id_to_modulus + .get(&id) + .ok_or(BlackBoxResolutionError::Failed( + func, + format!("could not find bigint of id {id}"), + )) + .cloned() + } + pub fn bigint_from_bytes( + &mut self, + inputs: &[u8], + modulus: &[u8], + output: u32, + ) -> Result<(), BlackBoxResolutionError> { + let bigint = BigUint::from_bytes_le(inputs); + self.bigint_id_to_value.insert(output, bigint); + let modulus = BigUint::from_bytes_le(modulus); + self.bigint_id_to_modulus.insert(output, modulus); + Ok(()) + } + + pub fn bigint_to_bytes(&self, input: u32) -> Result, BlackBoxResolutionError> { + let bigint = self.get_bigint(input, BlackBoxFunc::BigIntToLeBytes)?; + Ok(bigint.to_bytes_le()) + } + + pub fn bigint_op( + &mut self, + lhs: u32, + rhs: u32, + output: u32, + func: BlackBoxFunc, + ) -> Result<(), BlackBoxResolutionError> { + let modulus = self.get_modulus(lhs, func)?; + let lhs = self.get_bigint(lhs, func)?; + let rhs = self.get_bigint(rhs, func)?; + let mut result = match func { + BlackBoxFunc::BigIntAdd => lhs + rhs, + BlackBoxFunc::BigIntSub => { + if lhs >= rhs { + &lhs - &rhs + } else { + &lhs + &modulus - &rhs + } + } + BlackBoxFunc::BigIntMul => lhs * rhs, + BlackBoxFunc::BigIntDiv => { + lhs * rhs.modpow(&(&modulus - BigUint::from(2_u32)), &modulus) + } //TODO ensure that modulus is prime + _ => unreachable!("ICE - bigint_op must be called for an operation"), + }; + if result > modulus { + let q = &result / &modulus; + result -= q * &modulus; + } + self.bigint_id_to_value.insert(output, result); + self.bigint_id_to_modulus.insert(output, modulus); + Ok(()) + } +} diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs b/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs index f0ab45612299..fab67467d9ab 100644 --- a/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs +++ b/noir/noir-repo/acvm-repo/blackbox_solver/src/curve_specific_solver.rs @@ -11,7 +11,7 @@ pub trait BlackBoxFunctionSolver { &self, public_key_x: &FieldElement, public_key_y: &FieldElement, - signature: &[u8], + signature: &[u8; 64], message: &[u8], ) -> Result; fn pedersen_commitment( @@ -59,7 +59,7 @@ impl BlackBoxFunctionSolver for StubbedBlackBoxSolver { &self, _public_key_x: &FieldElement, _public_key_y: &FieldElement, - _signature: &[u8], + _signature: &[u8; 64], _message: &[u8], ) -> Result { Err(Self::fail(BlackBoxFunc::SchnorrVerify)) diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/src/lib.rs b/noir/noir-repo/acvm-repo/blackbox_solver/src/lib.rs index dc798bdab326..0f57f2ce7da3 100644 --- a/noir/noir-repo/acvm-repo/blackbox_solver/src/lib.rs +++ b/noir/noir-repo/acvm-repo/blackbox_solver/src/lib.rs @@ -10,10 +10,12 @@ use acir::BlackBoxFunc; use thiserror::Error; +mod bigint; mod curve_specific_solver; mod ecdsa; mod hash; +pub use bigint::BigIntSolver; pub use curve_specific_solver::{BlackBoxFunctionSolver, StubbedBlackBoxSolver}; pub use ecdsa::{ecdsa_secp256k1_verify, ecdsa_secp256r1_verify}; pub use hash::{blake2s, blake3, keccak256, keccakf1600, sha256, sha256compression}; diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/Cargo.toml b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/Cargo.toml index 318833180ea2..448642e1a9e2 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/Cargo.toml +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/Cargo.toml @@ -16,8 +16,9 @@ repository.workspace = true acir.workspace = true acvm_blackbox_solver.workspace = true thiserror.workspace = true -num-traits.workspace = true cfg-if = "1.0.0" +hex.workspace = true +lazy_static = "1.4" # BN254 fixed base scalar multiplication solver grumpkin = { version = "0.1.0", package = "noir_grumpkin", features = ["std"] } @@ -38,6 +39,18 @@ js-sys.workspace = true getrandom.workspace = true wasmer = "4.2.6" +[dev-dependencies] +criterion = "0.5.0" +pprof = { version = "0.12", features = [ + "flamegraph", + "frame-pointer", + "criterion", +] } + +[[bench]] +name = "criterion" +harness = false + [features] default = ["bn254"] bn254 = ["acir/bn254"] diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/benches/criterion.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/benches/criterion.rs new file mode 100644 index 000000000000..eb529ed2c115 --- /dev/null +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/benches/criterion.rs @@ -0,0 +1,21 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use std::{hint::black_box, time::Duration}; + +use acir::FieldElement; +use bn254_blackbox_solver::poseidon2_permutation; + +use pprof::criterion::{Output, PProfProfiler}; + +fn bench_poseidon2(c: &mut Criterion) { + let inputs = [FieldElement::zero(); 4]; + + c.bench_function("poseidon2", |b| b.iter(|| poseidon2_permutation(black_box(&inputs), 4))); +} + +criterion_group!( + name = benches; + config = Criterion::default().sample_size(40).measurement_time(Duration::from_secs(20)).with_profiler(PProfProfiler::new(100, Output::Flamegraph(None))); + targets = bench_poseidon2 +); + +criterion_main!(benches); diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 5e68c7d40304..cd91c290f494 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -47,17 +47,29 @@ pub fn fixed_base_scalar_mul( } } +fn create_point(x: FieldElement, y: FieldElement) -> Result { + let point = grumpkin::SWAffine::new_unchecked(x.into_repr(), y.into_repr()); + if !point.is_on_curve() { + return Err(format!("Point ({}, {}) is not on curve", x.to_hex(), y.to_hex())); + }; + if !point.is_in_correct_subgroup_assuming_on_curve() { + return Err(format!("Point ({}, {}) is not in correct subgroup", x.to_hex(), y.to_hex())); + }; + Ok(point) +} + pub fn embedded_curve_add( input1_x: FieldElement, input1_y: FieldElement, input2_x: FieldElement, input2_y: FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - let mut point1 = grumpkin::SWAffine::new(input1_x.into_repr(), input1_y.into_repr()); - let point2 = grumpkin::SWAffine::new(input2_x.into_repr(), input2_y.into_repr()); - let res = point1 + point2; - point1 = res.into(); - if let Some((res_x, res_y)) = point1.xy() { + let point1 = create_point(input1_x, input1_y) + .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; + let point2 = create_point(input2_x, input2_y) + .map_err(|e| BlackBoxResolutionError::Failed(BlackBoxFunc::EmbeddedCurveAdd, e))?; + let res = grumpkin::SWAffine::from(point1 + point2); + if let Some((res_x, res_y)) = res.xy() { Ok((FieldElement::from_repr(*res_x), FieldElement::from_repr(*res_y))) } else { Err(BlackBoxResolutionError::Failed( @@ -72,6 +84,7 @@ mod grumpkin_fixed_base_scalar_mul { use ark_ff::BigInteger; use super::*; + #[test] fn smoke_test() -> Result<(), BlackBoxResolutionError> { let input = FieldElement::one(); @@ -84,6 +97,7 @@ mod grumpkin_fixed_base_scalar_mul { assert_eq!(y, res.1.to_hex()); Ok(()) } + #[test] fn low_high_smoke_test() -> Result<(), BlackBoxResolutionError> { let low = FieldElement::one(); @@ -103,9 +117,9 @@ mod grumpkin_fixed_base_scalar_mul { let max_limb = FieldElement::from(u128::MAX); let invalid_limb = max_limb + FieldElement::one(); - let expected_error = Err(BlackBoxResolutionError::Failed( + let expected_error = Err(BlackBoxResolutionError::Failed( BlackBoxFunc::FixedBaseScalarMul, - "Limb 0000000000000000000000000000000100000000000000000000000000000000 is not less than 2^128".into() + "Limb 0000000000000000000000000000000100000000000000000000000000000000 is not less than 2^128".into(), )); let res = fixed_base_scalar_mul(&invalid_limb, &FieldElement::zero()); @@ -128,7 +142,23 @@ mod grumpkin_fixed_base_scalar_mul { res, Err(BlackBoxResolutionError::Failed( BlackBoxFunc::FixedBaseScalarMul, - "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 is not a valid grumpkin scalar".into() + "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 is not a valid grumpkin scalar".into(), + )) + ); + } + + #[test] + fn rejects_addition_of_points_not_in_curve() { + let x = FieldElement::from(1u128); + let y = FieldElement::from(2u128); + + let res = embedded_curve_add(x, y, x, y); + + assert_eq!( + res, + Err(BlackBoxResolutionError::Failed( + BlackBoxFunc::EmbeddedCurveAdd, + "Point (0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000002) is not on curve".into(), )) ); } diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs index 231594170e37..25b10252a784 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -10,7 +10,7 @@ mod poseidon2; mod wasm; pub use fixed_base_scalar_mul::{embedded_curve_add, fixed_base_scalar_mul}; -use poseidon2::Poseidon2; +pub use poseidon2::poseidon2_permutation; use wasm::Barretenberg; use self::wasm::{Pedersen, SchnorrSig}; @@ -52,7 +52,7 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { &self, public_key_x: &FieldElement, public_key_y: &FieldElement, - signature: &[u8], + signature: &[u8; 64], message: &[u8], ) -> Result { let pub_key_bytes: Vec = @@ -112,7 +112,6 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { inputs: &[FieldElement], len: u32, ) -> Result, BlackBoxResolutionError> { - let poseidon = Poseidon2::new(); - poseidon.permutation(inputs, len) + poseidon2_permutation(inputs, len) } } diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs index e0ed5bcd0531..65058e150991 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs @@ -1,9 +1,20 @@ use acir::FieldElement; use acvm_blackbox_solver::BlackBoxResolutionError; -use num_bigint::BigUint; -use num_traits::Num; +use lazy_static::lazy_static; -pub(crate) struct Poseidon2 { +pub fn poseidon2_permutation( + inputs: &[FieldElement], + len: u32, +) -> Result, BlackBoxResolutionError> { + let poseidon = Poseidon2::new(); + poseidon.permutation(inputs, len) +} + +pub(crate) struct Poseidon2<'a> { + config: &'a Poseidon2Config, +} + +struct Poseidon2Config { t: u32, rounds_f: u32, rounds_p: u32, @@ -11,929 +22,415 @@ pub(crate) struct Poseidon2 { round_constant: [[FieldElement; 4]; 64], } -impl Poseidon2 { +fn field_from_hex(hex: &str) -> FieldElement { + FieldElement::from_be_bytes_reduce(&hex::decode(hex).expect("Should be passed only valid hex")) +} + +lazy_static! { + static ref INTERNAL_MATRIX_DIAGONAL: [FieldElement; 4] = [ + field_from_hex("10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7"), + field_from_hex("0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b"), + field_from_hex("00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15"), + field_from_hex("222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b"), + ]; + static ref ROUND_CONSTANT: [[FieldElement; 4]; 64] = [ + [ + field_from_hex("19b849f69450b06848da1d39bd5e4a4302bb86744edc26238b0878e269ed23e5"), + field_from_hex("265ddfe127dd51bd7239347b758f0a1320eb2cc7450acc1dad47f80c8dcf34d6"), + field_from_hex("199750ec472f1809e0f66a545e1e51624108ac845015c2aa3dfc36bab497d8aa"), + field_from_hex("157ff3fe65ac7208110f06a5f74302b14d743ea25067f0ffd032f787c7f1cdf8"), + ], + [ + field_from_hex("2e49c43c4569dd9c5fd35ac45fca33f10b15c590692f8beefe18f4896ac94902"), + field_from_hex("0e35fb89981890520d4aef2b6d6506c3cb2f0b6973c24fa82731345ffa2d1f1e"), + field_from_hex("251ad47cb15c4f1105f109ae5e944f1ba9d9e7806d667ffec6fe723002e0b996"), + field_from_hex("13da07dc64d428369873e97160234641f8beb56fdd05e5f3563fa39d9c22df4e"), + ], + [ + field_from_hex("0c009b84e650e6d23dc00c7dccef7483a553939689d350cd46e7b89055fd4738"), + field_from_hex("011f16b1c63a854f01992e3956f42d8b04eb650c6d535eb0203dec74befdca06"), + field_from_hex("0ed69e5e383a688f209d9a561daa79612f3f78d0467ad45485df07093f367549"), + field_from_hex("04dba94a7b0ce9e221acad41472b6bbe3aec507f5eb3d33f463672264c9f789b"), + ], + [ + field_from_hex("0a3f2637d840f3a16eb094271c9d237b6036757d4bb50bf7ce732ff1d4fa28e8"), + field_from_hex("259a666f129eea198f8a1c502fdb38fa39b1f075569564b6e54a485d1182323f"), + field_from_hex("28bf7459c9b2f4c6d8e7d06a4ee3a47f7745d4271038e5157a32fdf7ede0d6a1"), + field_from_hex("0a1ca941f057037526ea200f489be8d4c37c85bbcce6a2aeec91bd6941432447"), + ], + [ + field_from_hex("0c6f8f958be0e93053d7fd4fc54512855535ed1539f051dcb43a26fd926361cf"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("123106a93cd17578d426e8128ac9d90aa9e8a00708e296e084dd57e69caaf811"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("26e1ba52ad9285d97dd3ab52f8e840085e8fa83ff1e8f1877b074867cd2dee75"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1cb55cad7bd133de18a64c5c47b9c97cbe4d8b7bf9e095864471537e6a4ae2c5"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1dcd73e46acd8f8e0e2c7ce04bde7f6d2a53043d5060a41c7143f08e6e9055d0"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("011003e32f6d9c66f5852f05474a4def0cda294a0eb4e9b9b12b9bb4512e5574"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("2b1e809ac1d10ab29ad5f20d03a57dfebadfe5903f58bafed7c508dd2287ae8c"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("2539de1785b735999fb4dac35ee17ed0ef995d05ab2fc5faeaa69ae87bcec0a5"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("0c246c5a2ef8ee0126497f222b3e0a0ef4e1c3d41c86d46e43982cb11d77951d"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("192089c4974f68e95408148f7c0632edbb09e6a6ad1a1c2f3f0305f5d03b527b"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1eae0ad8ab68b2f06a0ee36eeb0d0c058529097d91096b756d8fdc2fb5a60d85"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("179190e5d0e22179e46f8282872abc88db6e2fdc0dee99e69768bd98c5d06bfb"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("29bb9e2c9076732576e9a81c7ac4b83214528f7db00f31bf6cafe794a9b3cd1c"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("225d394e42207599403efd0c2464a90d52652645882aac35b10e590e6e691e08"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("064760623c25c8cf753d238055b444532be13557451c087de09efd454b23fd59"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("10ba3a0e01df92e87f301c4b716d8a394d67f4bf42a75c10922910a78f6b5b87"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("0e070bf53f8451b24f9c6e96b0c2a801cb511bc0c242eb9d361b77693f21471c"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1b94cd61b051b04dd39755ff93821a73ccd6cb11d2491d8aa7f921014de252fb"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1d7cb39bafb8c744e148787a2e70230f9d4e917d5713bb050487b5aa7d74070b"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("2ec93189bd1ab4f69117d0fe980c80ff8785c2961829f701bb74ac1f303b17db"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("2db366bfdd36d277a692bb825b86275beac404a19ae07a9082ea46bd83517926"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("062100eb485db06269655cf186a68532985275428450359adc99cec6960711b8"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("0761d33c66614aaa570e7f1e8244ca1120243f92fa59e4f900c567bf41f5a59b"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("20fc411a114d13992c2705aa034e3f315d78608a0f7de4ccf7a72e494855ad0d"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("25b5c004a4bdfcb5add9ec4e9ab219ba102c67e8b3effb5fc3a30f317250bc5a"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("23b1822d278ed632a494e58f6df6f5ed038b186d8474155ad87e7dff62b37f4b"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("22734b4c5c3f9493606c4ba9012499bf0f14d13bfcfcccaa16102a29cc2f69e0"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("26c0c8fe09eb30b7e27a74dc33492347e5bdff409aa3610254413d3fad795ce5"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("070dd0ccb6bd7bbae88eac03fa1fbb26196be3083a809829bbd626df348ccad9"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("12b6595bdb329b6fb043ba78bb28c3bec2c0a6de46d8c5ad6067c4ebfd4250da"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("248d97d7f76283d63bec30e7a5876c11c06fca9b275c671c5e33d95bb7e8d729"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1a306d439d463b0816fc6fd64cc939318b45eb759ddde4aa106d15d9bd9baaaa"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("28a8f8372e3c38daced7c00421cb4621f4f1b54ddc27821b0d62d3d6ec7c56cf"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("0094975717f9a8a8bb35152f24d43294071ce320c829f388bc852183e1e2ce7e"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("04d5ee4c3aa78f7d80fde60d716480d3593f74d4f653ae83f4103246db2e8d65"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("2a6cf5e9aa03d4336349ad6fb8ed2269c7bef54b8822cc76d08495c12efde187"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("2304d31eaab960ba9274da43e19ddeb7f792180808fd6e43baae48d7efcba3f3"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("03fd9ac865a4b2a6d5e7009785817249bff08a7e0726fcb4e1c11d39d199f0b0"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("00b7258ded52bbda2248404d55ee5044798afc3a209193073f7954d4d63b0b64"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("159f81ada0771799ec38fca2d4bf65ebb13d3a74f3298db36272c5ca65e92d9a"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1ef90e67437fbc8550237a75bc28e3bb9000130ea25f0c5471e144cf4264431f"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1e65f838515e5ff0196b49aa41a2d2568df739bc176b08ec95a79ed82932e30d"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("2b1b045def3a166cec6ce768d079ba74b18c844e570e1f826575c1068c94c33f"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("0832e5753ceb0ff6402543b1109229c165dc2d73bef715e3f1c6e07c168bb173"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("02f614e9cedfb3dc6b762ae0a37d41bab1b841c2e8b6451bc5a8e3c390b6ad16"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("0e2427d38bd46a60dd640b8e362cad967370ebb777bedff40f6a0be27e7ed705"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("0493630b7c670b6deb7c84d414e7ce79049f0ec098c3c7c50768bbe29214a53a"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("22ead100e8e482674decdab17066c5a26bb1515355d5461a3dc06cc85327cea9"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("25b3e56e655b42cdaae2626ed2554d48583f1ae35626d04de5084e0b6d2a6f16"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1e32752ada8836ef5837a6cde8ff13dbb599c336349e4c584b4fdc0a0cf6f9d0"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("2fa2a871c15a387cc50f68f6f3c3455b23c00995f05078f672a9864074d412e5"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("2f569b8a9a4424c9278e1db7311e889f54ccbf10661bab7fcd18e7c7a7d83505"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("044cb455110a8fdd531ade530234c518a7df93f7332ffd2144165374b246b43d"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("227808de93906d5d420246157f2e42b191fe8c90adfe118178ddc723a5319025"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("02fcca2934e046bc623adead873579865d03781ae090ad4a8579d2e7a6800355"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("0ef915f0ac120b876abccceb344a1d36bad3f3c5ab91a8ddcbec2e060d8befac"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + field_from_hex("0000000000000000000000000000000000000000000000000000000000000000"), + ], + [ + field_from_hex("1797130f4b7a3e1777eb757bc6f287f6ab0fb85f6be63b09f3b16ef2b1405d38"), + field_from_hex("0a76225dc04170ae3306c85abab59e608c7f497c20156d4d36c668555decc6e5"), + field_from_hex("1fffb9ec1992d66ba1e77a7b93209af6f8fa76d48acb664796174b5326a31a5c"), + field_from_hex("25721c4fc15a3f2853b57c338fa538d85f8fbba6c6b9c6090611889b797b9c5f"), + ], + [ + field_from_hex("0c817fd42d5f7a41215e3d07ba197216adb4c3790705da95eb63b982bfcaf75a"), + field_from_hex("13abe3f5239915d39f7e13c2c24970b6df8cf86ce00a22002bc15866e52b5a96"), + field_from_hex("2106feea546224ea12ef7f39987a46c85c1bc3dc29bdbd7a92cd60acb4d391ce"), + field_from_hex("21ca859468a746b6aaa79474a37dab49f1ca5a28c748bc7157e1b3345bb0f959"), + ], + [ + field_from_hex("05ccd6255c1e6f0c5cf1f0df934194c62911d14d0321662a8f1a48999e34185b"), + field_from_hex("0f0e34a64b70a626e464d846674c4c8816c4fb267fe44fe6ea28678cb09490a4"), + field_from_hex("0558531a4e25470c6157794ca36d0e9647dbfcfe350d64838f5b1a8a2de0d4bf"), + field_from_hex("09d3dca9173ed2faceea125157683d18924cadad3f655a60b72f5864961f1455"), + ], + [ + field_from_hex("0328cbd54e8c0913493f866ed03d218bf23f92d68aaec48617d4c722e5bd4335"), + field_from_hex("2bf07216e2aff0a223a487b1a7094e07e79e7bcc9798c648ee3347dd5329d34b"), + field_from_hex("1daf345a58006b736499c583cb76c316d6f78ed6a6dffc82111e11a63fe412df"), + field_from_hex("176563472456aaa746b694c60e1823611ef39039b2edc7ff391e6f2293d2c404"), + ], + ]; + static ref POSEIDON2_CONFIG: Poseidon2Config = Poseidon2Config { + t: 4, + rounds_f: 8, + rounds_p: 56, + internal_matrix_diagonal: *INTERNAL_MATRIX_DIAGONAL, + round_constant: *ROUND_CONSTANT, + }; +} + +impl<'a> Poseidon2<'a> { pub(crate) fn new() -> Self { - Poseidon2 { - t: 4, - rounds_f: 8, - rounds_p: 56, - internal_matrix_diagonal: [ - Poseidon2::field_from_hex( - "0x10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7", - ), - Poseidon2::field_from_hex( - "0x0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b", - ), - Poseidon2::field_from_hex( - "0x00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15", - ), - Poseidon2::field_from_hex( - "0x222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b", - ), - ], - round_constant: [ - [ - Poseidon2::field_from_hex( - "0x19b849f69450b06848da1d39bd5e4a4302bb86744edc26238b0878e269ed23e5", - ), - Poseidon2::field_from_hex( - "0x265ddfe127dd51bd7239347b758f0a1320eb2cc7450acc1dad47f80c8dcf34d6", - ), - Poseidon2::field_from_hex( - "0x199750ec472f1809e0f66a545e1e51624108ac845015c2aa3dfc36bab497d8aa", - ), - Poseidon2::field_from_hex( - "0x157ff3fe65ac7208110f06a5f74302b14d743ea25067f0ffd032f787c7f1cdf8", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2e49c43c4569dd9c5fd35ac45fca33f10b15c590692f8beefe18f4896ac94902", - ), - Poseidon2::field_from_hex( - "0x0e35fb89981890520d4aef2b6d6506c3cb2f0b6973c24fa82731345ffa2d1f1e", - ), - Poseidon2::field_from_hex( - "0x251ad47cb15c4f1105f109ae5e944f1ba9d9e7806d667ffec6fe723002e0b996", - ), - Poseidon2::field_from_hex( - "0x13da07dc64d428369873e97160234641f8beb56fdd05e5f3563fa39d9c22df4e", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0c009b84e650e6d23dc00c7dccef7483a553939689d350cd46e7b89055fd4738", - ), - Poseidon2::field_from_hex( - "0x011f16b1c63a854f01992e3956f42d8b04eb650c6d535eb0203dec74befdca06", - ), - Poseidon2::field_from_hex( - "0x0ed69e5e383a688f209d9a561daa79612f3f78d0467ad45485df07093f367549", - ), - Poseidon2::field_from_hex( - "0x04dba94a7b0ce9e221acad41472b6bbe3aec507f5eb3d33f463672264c9f789b", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0a3f2637d840f3a16eb094271c9d237b6036757d4bb50bf7ce732ff1d4fa28e8", - ), - Poseidon2::field_from_hex( - "0x259a666f129eea198f8a1c502fdb38fa39b1f075569564b6e54a485d1182323f", - ), - Poseidon2::field_from_hex( - "0x28bf7459c9b2f4c6d8e7d06a4ee3a47f7745d4271038e5157a32fdf7ede0d6a1", - ), - Poseidon2::field_from_hex( - "0x0a1ca941f057037526ea200f489be8d4c37c85bbcce6a2aeec91bd6941432447", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0c6f8f958be0e93053d7fd4fc54512855535ed1539f051dcb43a26fd926361cf", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x123106a93cd17578d426e8128ac9d90aa9e8a00708e296e084dd57e69caaf811", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x26e1ba52ad9285d97dd3ab52f8e840085e8fa83ff1e8f1877b074867cd2dee75", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1cb55cad7bd133de18a64c5c47b9c97cbe4d8b7bf9e095864471537e6a4ae2c5", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1dcd73e46acd8f8e0e2c7ce04bde7f6d2a53043d5060a41c7143f08e6e9055d0", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x011003e32f6d9c66f5852f05474a4def0cda294a0eb4e9b9b12b9bb4512e5574", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2b1e809ac1d10ab29ad5f20d03a57dfebadfe5903f58bafed7c508dd2287ae8c", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2539de1785b735999fb4dac35ee17ed0ef995d05ab2fc5faeaa69ae87bcec0a5", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0c246c5a2ef8ee0126497f222b3e0a0ef4e1c3d41c86d46e43982cb11d77951d", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x192089c4974f68e95408148f7c0632edbb09e6a6ad1a1c2f3f0305f5d03b527b", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1eae0ad8ab68b2f06a0ee36eeb0d0c058529097d91096b756d8fdc2fb5a60d85", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x179190e5d0e22179e46f8282872abc88db6e2fdc0dee99e69768bd98c5d06bfb", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x29bb9e2c9076732576e9a81c7ac4b83214528f7db00f31bf6cafe794a9b3cd1c", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x225d394e42207599403efd0c2464a90d52652645882aac35b10e590e6e691e08", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x064760623c25c8cf753d238055b444532be13557451c087de09efd454b23fd59", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x10ba3a0e01df92e87f301c4b716d8a394d67f4bf42a75c10922910a78f6b5b87", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0e070bf53f8451b24f9c6e96b0c2a801cb511bc0c242eb9d361b77693f21471c", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1b94cd61b051b04dd39755ff93821a73ccd6cb11d2491d8aa7f921014de252fb", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1d7cb39bafb8c744e148787a2e70230f9d4e917d5713bb050487b5aa7d74070b", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2ec93189bd1ab4f69117d0fe980c80ff8785c2961829f701bb74ac1f303b17db", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2db366bfdd36d277a692bb825b86275beac404a19ae07a9082ea46bd83517926", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x062100eb485db06269655cf186a68532985275428450359adc99cec6960711b8", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0761d33c66614aaa570e7f1e8244ca1120243f92fa59e4f900c567bf41f5a59b", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x20fc411a114d13992c2705aa034e3f315d78608a0f7de4ccf7a72e494855ad0d", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x25b5c004a4bdfcb5add9ec4e9ab219ba102c67e8b3effb5fc3a30f317250bc5a", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x23b1822d278ed632a494e58f6df6f5ed038b186d8474155ad87e7dff62b37f4b", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x22734b4c5c3f9493606c4ba9012499bf0f14d13bfcfcccaa16102a29cc2f69e0", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x26c0c8fe09eb30b7e27a74dc33492347e5bdff409aa3610254413d3fad795ce5", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x070dd0ccb6bd7bbae88eac03fa1fbb26196be3083a809829bbd626df348ccad9", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x12b6595bdb329b6fb043ba78bb28c3bec2c0a6de46d8c5ad6067c4ebfd4250da", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x248d97d7f76283d63bec30e7a5876c11c06fca9b275c671c5e33d95bb7e8d729", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1a306d439d463b0816fc6fd64cc939318b45eb759ddde4aa106d15d9bd9baaaa", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x28a8f8372e3c38daced7c00421cb4621f4f1b54ddc27821b0d62d3d6ec7c56cf", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0094975717f9a8a8bb35152f24d43294071ce320c829f388bc852183e1e2ce7e", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x04d5ee4c3aa78f7d80fde60d716480d3593f74d4f653ae83f4103246db2e8d65", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2a6cf5e9aa03d4336349ad6fb8ed2269c7bef54b8822cc76d08495c12efde187", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2304d31eaab960ba9274da43e19ddeb7f792180808fd6e43baae48d7efcba3f3", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x03fd9ac865a4b2a6d5e7009785817249bff08a7e0726fcb4e1c11d39d199f0b0", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x00b7258ded52bbda2248404d55ee5044798afc3a209193073f7954d4d63b0b64", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x159f81ada0771799ec38fca2d4bf65ebb13d3a74f3298db36272c5ca65e92d9a", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1ef90e67437fbc8550237a75bc28e3bb9000130ea25f0c5471e144cf4264431f", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1e65f838515e5ff0196b49aa41a2d2568df739bc176b08ec95a79ed82932e30d", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2b1b045def3a166cec6ce768d079ba74b18c844e570e1f826575c1068c94c33f", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0832e5753ceb0ff6402543b1109229c165dc2d73bef715e3f1c6e07c168bb173", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x02f614e9cedfb3dc6b762ae0a37d41bab1b841c2e8b6451bc5a8e3c390b6ad16", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0e2427d38bd46a60dd640b8e362cad967370ebb777bedff40f6a0be27e7ed705", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0493630b7c670b6deb7c84d414e7ce79049f0ec098c3c7c50768bbe29214a53a", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x22ead100e8e482674decdab17066c5a26bb1515355d5461a3dc06cc85327cea9", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x25b3e56e655b42cdaae2626ed2554d48583f1ae35626d04de5084e0b6d2a6f16", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1e32752ada8836ef5837a6cde8ff13dbb599c336349e4c584b4fdc0a0cf6f9d0", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2fa2a871c15a387cc50f68f6f3c3455b23c00995f05078f672a9864074d412e5", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x2f569b8a9a4424c9278e1db7311e889f54ccbf10661bab7fcd18e7c7a7d83505", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x044cb455110a8fdd531ade530234c518a7df93f7332ffd2144165374b246b43d", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x227808de93906d5d420246157f2e42b191fe8c90adfe118178ddc723a5319025", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x02fcca2934e046bc623adead873579865d03781ae090ad4a8579d2e7a6800355", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0ef915f0ac120b876abccceb344a1d36bad3f3c5ab91a8ddcbec2e060d8befac", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - Poseidon2::field_from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ), - ], - [ - Poseidon2::field_from_hex( - "0x1797130f4b7a3e1777eb757bc6f287f6ab0fb85f6be63b09f3b16ef2b1405d38", - ), - Poseidon2::field_from_hex( - "0x0a76225dc04170ae3306c85abab59e608c7f497c20156d4d36c668555decc6e5", - ), - Poseidon2::field_from_hex( - "0x1fffb9ec1992d66ba1e77a7b93209af6f8fa76d48acb664796174b5326a31a5c", - ), - Poseidon2::field_from_hex( - "0x25721c4fc15a3f2853b57c338fa538d85f8fbba6c6b9c6090611889b797b9c5f", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0c817fd42d5f7a41215e3d07ba197216adb4c3790705da95eb63b982bfcaf75a", - ), - Poseidon2::field_from_hex( - "0x13abe3f5239915d39f7e13c2c24970b6df8cf86ce00a22002bc15866e52b5a96", - ), - Poseidon2::field_from_hex( - "0x2106feea546224ea12ef7f39987a46c85c1bc3dc29bdbd7a92cd60acb4d391ce", - ), - Poseidon2::field_from_hex( - "0x21ca859468a746b6aaa79474a37dab49f1ca5a28c748bc7157e1b3345bb0f959", - ), - ], - [ - Poseidon2::field_from_hex( - "0x05ccd6255c1e6f0c5cf1f0df934194c62911d14d0321662a8f1a48999e34185b", - ), - Poseidon2::field_from_hex( - "0x0f0e34a64b70a626e464d846674c4c8816c4fb267fe44fe6ea28678cb09490a4", - ), - Poseidon2::field_from_hex( - "0x0558531a4e25470c6157794ca36d0e9647dbfcfe350d64838f5b1a8a2de0d4bf", - ), - Poseidon2::field_from_hex( - "0x09d3dca9173ed2faceea125157683d18924cadad3f655a60b72f5864961f1455", - ), - ], - [ - Poseidon2::field_from_hex( - "0x0328cbd54e8c0913493f866ed03d218bf23f92d68aaec48617d4c722e5bd4335", - ), - Poseidon2::field_from_hex( - "0x2bf07216e2aff0a223a487b1a7094e07e79e7bcc9798c648ee3347dd5329d34b", - ), - Poseidon2::field_from_hex( - "0x1daf345a58006b736499c583cb76c316d6f78ed6a6dffc82111e11a63fe412df", - ), - Poseidon2::field_from_hex( - "0x176563472456aaa746b694c60e1823611ef39039b2edc7ff391e6f2293d2c404", - ), - ], - ], - } - } - fn field_from_hex(hex: &str) -> FieldElement { - let bigint = BigUint::from_str_radix(hex.strip_prefix("0x").unwrap(), 16).unwrap(); - FieldElement::from_be_bytes_reduce(&bigint.to_bytes_be()) + Poseidon2 { config: &POSEIDON2_CONFIG } } fn single_box(x: FieldElement) -> FieldElement { @@ -948,7 +445,9 @@ impl Poseidon2 { } fn add_round_constants(&self, state: &mut [FieldElement], round: usize) { - for (state_element, constant_element) in state.iter_mut().zip(self.round_constant[round]) { + for (state_element, constant_element) in + state.iter_mut().zip(self.config.round_constant[round]) + { *state_element += constant_element; } } @@ -982,7 +481,7 @@ impl Poseidon2 { sum += *i; } for (index, i) in input.iter_mut().enumerate() { - *i = *i * self.internal_matrix_diagonal[index]; + *i = *i * self.config.internal_matrix_diagonal[index]; *i += sum; } } @@ -1002,10 +501,10 @@ impl Poseidon2 { ), )); } - if len != self.t { + if len != self.config.t { return Err(BlackBoxResolutionError::Failed( acir::BlackBoxFunc::Poseidon2Permutation, - format!("Expected {} values but encountered {}", self.t, len), + format!("Expected {} values but encountered {}", self.config.t, len), )); } // Read witness assignments @@ -1017,22 +516,22 @@ impl Poseidon2 { Self::matrix_multiplication_4x4(&mut state); // First set of external rounds - let rf_first = self.rounds_f / 2; + let rf_first = self.config.rounds_f / 2; for r in 0..rf_first { self.add_round_constants(&mut state, r as usize); Self::s_box(&mut state); Self::matrix_multiplication_4x4(&mut state); } // Internal rounds - let p_end = rf_first + self.rounds_p; + let p_end = rf_first + self.config.rounds_p; for r in rf_first..p_end { - state[0] += self.round_constant[r as usize][0]; + state[0] += self.config.round_constant[r as usize][0]; state[0] = Self::single_box(state[0]); self.internal_m_multiplication(&mut state); } // Remaining external rounds - let num_rounds = self.rounds_f + self.rounds_p; + let num_rounds = self.config.rounds_f + self.config.rounds_p; for i in p_end..num_rounds { self.add_round_constants(&mut state, i as usize); Self::s_box(&mut state); @@ -1041,3 +540,24 @@ impl Poseidon2 { Ok(state.into()) } } + +#[cfg(test)] +mod test { + use acir::FieldElement; + + use super::{field_from_hex, poseidon2_permutation}; + + #[test] + fn smoke_test() { + let inputs = [FieldElement::zero(); 4]; + let result = poseidon2_permutation(&inputs, 4).expect("should successfully permute"); + + let expected_result = [ + field_from_hex("18DFB8DC9B82229CFF974EFEFC8DF78B1CE96D9D844236B496785C698BC6732E"), + field_from_hex("095C230D1D37A246E8D2D5A63B165FE0FADE040D442F61E25F0590E5FB76F839"), + field_from_hex("0BB9545846E1AFA4FA3C97414A60A20FC4949F537A68CCECA34C5CE71E28AA59"), + field_from_hex("18A4F34C9C6F99335FF7638B82AEED9018026618358873C982BBDDE265B2ED6D"), + ]; + assert_eq!(result, expected_result); + } +} diff --git a/noir/noir-repo/acvm-repo/brillig/src/opcodes.rs b/noir/noir-repo/acvm-repo/brillig/src/opcodes.rs index d13453519862..468fd88db45d 100644 --- a/noir/noir-repo/acvm-repo/brillig/src/opcodes.rs +++ b/noir/noir-repo/acvm-repo/brillig/src/opcodes.rs @@ -177,8 +177,11 @@ pub enum BrilligOpcode { source: MemoryAddress, }, BlackBox(BlackBoxOp), - /// Used to denote execution failure - Trap, + /// Used to denote execution failure, returning data after the offset + Trap { + revert_data_offset: usize, + revert_data_size: usize, + }, /// Stop execution, returning data after the offset Stop { return_data_offset: usize, diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs index 73981fb06259..19407da52dbe 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs @@ -1,5 +1,6 @@ use acir::brillig::{BlackBoxOp, HeapArray, HeapVector}; use acir::{BlackBoxFunc, FieldElement}; +use acvm_blackbox_solver::BigIntSolver; use acvm_blackbox_solver::{ blake2s, blake3, ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, keccakf1600, sha256, sha256compression, BlackBoxFunctionSolver, BlackBoxResolutionError, @@ -34,6 +35,7 @@ pub(crate) fn evaluate_black_box( op: &BlackBoxOp, solver: &Solver, memory: &mut Memory, + bigint_solver: &mut BigIntSolver, ) -> Result<(), BlackBoxResolutionError> { match op { BlackBoxOp::Sha256 { message, output } => { @@ -127,7 +129,8 @@ pub(crate) fn evaluate_black_box( let public_key_x = memory.read(*public_key_x).try_into().unwrap(); let public_key_y = memory.read(*public_key_y).try_into().unwrap(); let message: Vec = to_u8_vec(read_heap_vector(memory, message)); - let signature: Vec = to_u8_vec(read_heap_vector(memory, signature)); + let signature: [u8; 64] = + to_u8_vec(read_heap_vector(memory, signature)).try_into().unwrap(); let verified = solver.schnorr_verify(&public_key_x, &public_key_y, &signature, &message)?; memory.write(*result, verified.into()); @@ -177,12 +180,57 @@ pub(crate) fn evaluate_black_box( memory.write(*output, hash.into()); Ok(()) } - BlackBoxOp::BigIntAdd { .. } => todo!(), - BlackBoxOp::BigIntSub { .. } => todo!(), - BlackBoxOp::BigIntMul { .. } => todo!(), - BlackBoxOp::BigIntDiv { .. } => todo!(), - BlackBoxOp::BigIntFromLeBytes { .. } => todo!(), - BlackBoxOp::BigIntToLeBytes { .. } => todo!(), + BlackBoxOp::BigIntAdd { lhs, rhs, output } => { + let lhs = memory.read(*lhs).try_into().unwrap(); + let rhs = memory.read(*rhs).try_into().unwrap(); + let output = memory.read(*output).try_into().unwrap(); + bigint_solver.bigint_op(lhs, rhs, output, BlackBoxFunc::BigIntAdd)?; + Ok(()) + } + BlackBoxOp::BigIntSub { lhs, rhs, output } => { + let lhs = memory.read(*lhs).try_into().unwrap(); + let rhs = memory.read(*rhs).try_into().unwrap(); + let output = memory.read(*output).try_into().unwrap(); + bigint_solver.bigint_op(lhs, rhs, output, BlackBoxFunc::BigIntSub)?; + Ok(()) + } + BlackBoxOp::BigIntMul { lhs, rhs, output } => { + let lhs = memory.read(*lhs).try_into().unwrap(); + let rhs = memory.read(*rhs).try_into().unwrap(); + let output = memory.read(*output).try_into().unwrap(); + bigint_solver.bigint_op(lhs, rhs, output, BlackBoxFunc::BigIntMul)?; + Ok(()) + } + BlackBoxOp::BigIntDiv { lhs, rhs, output } => { + let lhs = memory.read(*lhs).try_into().unwrap(); + let rhs = memory.read(*rhs).try_into().unwrap(); + let output = memory.read(*output).try_into().unwrap(); + bigint_solver.bigint_op(lhs, rhs, output, BlackBoxFunc::BigIntDiv)?; + Ok(()) + } + BlackBoxOp::BigIntFromLeBytes { inputs, modulus, output } => { + let input = read_heap_vector(memory, inputs); + let input: Vec = input.iter().map(|x| x.try_into().unwrap()).collect(); + let modulus = read_heap_vector(memory, modulus); + let modulus: Vec = modulus.iter().map(|x| x.try_into().unwrap()).collect(); + let output = memory.read(*output).try_into().unwrap(); + bigint_solver.bigint_from_bytes(&input, &modulus, output)?; + Ok(()) + } + BlackBoxOp::BigIntToLeBytes { input, output } => { + let input: u32 = memory.read(*input).try_into().unwrap(); + let bytes = bigint_solver.bigint_to_bytes(input)?; + let mut values = Vec::new(); + for i in 0..32 { + if i < bytes.len() { + values.push(bytes[i].into()); + } else { + values.push(0_u8.into()); + } + } + memory.write_slice(memory.read_ref(output.pointer), &values); + Ok(()) + } BlackBoxOp::Poseidon2Permutation { message, output, len } => { let input = read_heap_vector(memory, message); let input: Vec = input.iter().map(|x| x.try_into().unwrap()).collect(); @@ -256,7 +304,7 @@ fn black_box_function_from_op(op: &BlackBoxOp) -> BlackBoxFunc { #[cfg(test)] mod test { use acir::brillig::{BlackBoxOp, MemoryAddress}; - use acvm_blackbox_solver::StubbedBlackBoxSolver; + use acvm_blackbox_solver::{BigIntSolver, StubbedBlackBoxSolver}; use crate::{ black_box::{evaluate_black_box, to_u8_vec, to_value_vec}, @@ -281,7 +329,8 @@ mod test { output: HeapArray { pointer: 2.into(), size: 32 }, }; - evaluate_black_box(&op, &StubbedBlackBoxSolver, &mut memory).unwrap(); + evaluate_black_box(&op, &StubbedBlackBoxSolver, &mut memory, &mut BigIntSolver::default()) + .unwrap(); let result = memory.read_slice(MemoryAddress(result_pointer), 32); diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs index 26d5da675769..75299670f948 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/lib.rs @@ -16,7 +16,7 @@ use acir::brillig::{ HeapVector, MemoryAddress, Opcode, ValueOrArray, }; use acir::FieldElement; -use acvm_blackbox_solver::BlackBoxFunctionSolver; +use acvm_blackbox_solver::{BigIntSolver, BlackBoxFunctionSolver}; use arithmetic::{evaluate_binary_field_op, evaluate_binary_int_op, BrilligArithmeticError}; use black_box::evaluate_black_box; use num_bigint::BigUint; @@ -32,6 +32,12 @@ mod memory; /// The error call stack contains the opcode indexes of the call stack at the time of failure, plus the index of the opcode that failed. pub type ErrorCallStack = Vec; +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum FailureReason { + Trap { revert_data_offset: usize, revert_data_size: usize }, + RuntimeError { message: String }, +} + #[derive(Debug, PartialEq, Eq, Clone)] pub enum VMStatus { Finished { @@ -40,7 +46,7 @@ pub enum VMStatus { }, InProgress, Failure { - message: String, + reason: FailureReason, call_stack: ErrorCallStack, }, /// The VM process is not solvable as a [foreign call][Opcode::ForeignCall] has been @@ -81,6 +87,8 @@ pub struct VM<'a, B: BlackBoxFunctionSolver> { call_stack: Vec, /// The solver for blackbox functions black_box_solver: &'a B, + // The solver for big integers + bigint_solver: BigIntSolver, } impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { @@ -101,6 +109,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { memory: Memory::default(), call_stack: Vec::new(), black_box_solver, + bigint_solver: Default::default(), } } @@ -138,13 +147,28 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.status(VMStatus::InProgress); } + fn get_error_stack(&self) -> Vec { + let mut error_stack: Vec<_> = self.call_stack.clone(); + error_stack.push(self.program_counter); + error_stack + } + /// Sets the current status of the VM to `fail`. /// Indicating that the VM encountered a `Trap` Opcode /// or an invalid state. + fn trap(&mut self, revert_data_offset: usize, revert_data_size: usize) -> VMStatus { + self.status(VMStatus::Failure { + call_stack: self.get_error_stack(), + reason: FailureReason::Trap { revert_data_offset, revert_data_size }, + }); + self.status.clone() + } + fn fail(&mut self, message: String) -> VMStatus { - let mut error_stack: Vec<_> = self.call_stack.clone(); - error_stack.push(self.program_counter); - self.status(VMStatus::Failure { call_stack: error_stack, message }); + self.status(VMStatus::Failure { + call_stack: self.get_error_stack(), + reason: FailureReason::RuntimeError { message }, + }); self.status.clone() } @@ -281,7 +305,9 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { } self.increment_program_counter() } - Opcode::Trap => self.fail("explicit trap hit in brillig".to_string()), + Opcode::Trap { revert_data_offset, revert_data_size } => { + self.trap(*revert_data_offset, *revert_data_size) + } Opcode::Stop { return_data_offset, return_data_size } => { self.finish(*return_data_offset, *return_data_size) } @@ -311,7 +337,12 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.increment_program_counter() } Opcode::BlackBox(black_box_op) => { - match evaluate_black_box(black_box_op, self.black_box_solver, &mut self.memory) { + match evaluate_black_box( + black_box_op, + self.black_box_solver, + &mut self.memory, + &mut self.bigint_solver, + ) { Ok(()) => self.increment_program_counter(), Err(e) => self.fail(e.to_string()), } @@ -684,7 +715,7 @@ mod tests { let jump_opcode = Opcode::Jump { location: 3 }; - let trap_opcode = Opcode::Trap; + let trap_opcode = Opcode::Trap { revert_data_offset: 0, revert_data_size: 0 }; let not_equal_cmp_opcode = Opcode::BinaryFieldOp { op: BinaryFieldOp::Equals, @@ -731,7 +762,7 @@ mod tests { assert_eq!( status, VMStatus::Failure { - message: "explicit trap hit in brillig".to_string(), + reason: FailureReason::Trap { revert_data_offset: 0, revert_data_size: 0 }, call_stack: vec![2] } ); diff --git a/noir/noir-repo/aztec_macros/src/lib.rs b/noir/noir-repo/aztec_macros/src/lib.rs index 48c30ab6ffad..dff3193a3272 100644 --- a/noir/noir-repo/aztec_macros/src/lib.rs +++ b/noir/noir-repo/aztec_macros/src/lib.rs @@ -3,6 +3,9 @@ mod utils; use transforms::{ compute_note_hash_and_nullifier::inject_compute_note_hash_and_nullifier, + contract_interface::{ + generate_contract_interface, stub_function, update_fn_signatures_in_contract_interface, + }, events::{generate_selector_impl, transform_events}, functions::{export_fn_abi, transform_function, transform_unconstrained}, note_interface::{generate_note_interface_impl, inject_note_exports}, @@ -59,7 +62,14 @@ fn transform( // Usage -> mut ast -> aztec_library::transform(&mut ast) // Covers all functions in the ast for submodule in ast.submodules.iter_mut().filter(|submodule| submodule.is_contract) { - if transform_module(&mut submodule.contents).map_err(|err| (err.into(), file_id))? { + if transform_module( + crate_id, + context, + &mut submodule.contents, + submodule.name.0.contents.as_str(), + ) + .map_err(|err| (err.into(), file_id))? + { check_for_aztec_dependency(crate_id, context)?; } } @@ -72,7 +82,12 @@ fn transform( /// Determines if ast nodes are annotated with aztec attributes. /// For annotated functions it calls the `transform` function which will perform the required transformations. /// Returns true if an annotated node is found, false otherwise -fn transform_module(module: &mut SortedModule) -> Result { +fn transform_module( + crate_id: &CrateId, + context: &HirContext, + module: &mut SortedModule, + module_name: &str, +) -> Result { let mut has_transformed_module = false; // Check for a user defined storage struct @@ -84,7 +99,12 @@ fn transform_module(module: &mut SortedModule) -> Result if !check_for_storage_implementation(module, &storage_struct_name) { generate_storage_implementation(module, &storage_struct_name)?; } - generate_storage_layout(module, storage_struct_name)?; + // Make sure we're only generating the storage layout for the root crate + // In case we got a contract importing other contracts for their interface, we + // don't want to generate the storage layout for them + if crate_id == context.root_crate_id() { + generate_storage_layout(module, storage_struct_name)?; + } } for structure in module.types.iter_mut() { @@ -102,6 +122,8 @@ fn transform_module(module: &mut SortedModule) -> Result .any(|attr| is_custom_attribute(attr, "aztec(initializer)")) }); + let mut stubs: Vec<_> = vec![]; + for func in module.functions.iter_mut() { let mut is_private = false; let mut is_public = false; @@ -129,15 +151,18 @@ fn transform_module(module: &mut SortedModule) -> Result // Apply transformations to the function based on collected attributes if is_private || is_public || is_public_vm { + let fn_type = if is_private { + "Private" + } else if is_public_vm { + "Avm" + } else { + "Public" + }; + stubs.push(stub_function(fn_type, func)); + export_fn_abi(&mut module.types, func)?; transform_function( - if is_private { - "Private" - } else if is_public_vm { - "Avm" - } else { - "Public" - }, + fn_type, func, storage_defined, is_initializer, @@ -171,6 +196,8 @@ fn transform_module(module: &mut SortedModule) -> Result span: Span::default(), }); } + + generate_contract_interface(module, module_name, &stubs)?; } Ok(has_transformed_module) @@ -189,7 +216,8 @@ fn transform_hir( transform_events(crate_id, context)?; inject_compute_note_hash_and_nullifier(crate_id, context)?; assign_storage_slots(crate_id, context)?; - inject_note_exports(crate_id, context) + inject_note_exports(crate_id, context)?; + update_fn_signatures_in_contract_interface(crate_id, context) } else { Ok(()) } diff --git a/noir/noir-repo/aztec_macros/src/transforms/compute_note_hash_and_nullifier.rs b/noir/noir-repo/aztec_macros/src/transforms/compute_note_hash_and_nullifier.rs index 1b6630935d94..4ff97a5dcae0 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/compute_note_hash_and_nullifier.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/compute_note_hash_and_nullifier.rs @@ -49,20 +49,20 @@ pub fn inject_compute_note_hash_and_nullifier( crate_id: &CrateId, context: &mut HirContext, ) -> Result<(), (AztecMacroError, FileId)> { - if let Some((module_id, file_id)) = get_contract_module_data(context, crate_id) { + if let Some((_, module_id, file_id)) = get_contract_module_data(context, crate_id) { // If compute_note_hash_and_nullifier is already defined by the user, we skip auto-generation in order to provide an // escape hatch for this mechanism. // TODO(#4647): improve this diagnosis and error messaging. - if check_for_compute_note_hash_and_nullifier_definition(crate_id, context) { + if context.crate_graph.root_crate_id() != crate_id + || check_for_compute_note_hash_and_nullifier_definition(crate_id, context) + { return Ok(()); } // In order to implement compute_note_hash_and_nullifier, we need to know all of the different note types the // contract might use. These are the types that are marked as #[aztec(note)]. - let note_types = fetch_notes(context) - .iter() - .map(|(_, note)| note.borrow().name.0.contents.clone()) - .collect::>(); + let note_types = + fetch_notes(context).iter().map(|(path, _)| path.to_string()).collect::>(); // We can now generate a version of compute_note_hash_and_nullifier tailored for the contract in this crate. let func = generate_compute_note_hash_and_nullifier(¬e_types); @@ -73,7 +73,14 @@ pub fn inject_compute_note_hash_and_nullifier( // pass an empty span. This function should not produce errors anyway so this should not matter. let location = Location::new(Span::empty(0), file_id); - inject_fn(crate_id, context, func, location, module_id, file_id); + inject_fn(crate_id, context, func, location, module_id, file_id).map_err(|err| { + ( + AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier { + secondary_message: err.secondary_message, + }, + file_id, + ) + })?; } Ok(()) } @@ -100,7 +107,7 @@ fn generate_compute_note_hash_and_nullifier_source(note_types: &[String]) -> Str // so we include a dummy version. " unconstrained fn compute_note_hash_and_nullifier( - contract_address: AztecAddress, + contract_address: dep::aztec::protocol_types::address::AztecAddress, nonce: Field, storage_slot: Field, note_type_id: Field, @@ -130,7 +137,7 @@ fn generate_compute_note_hash_and_nullifier_source(note_types: &[String]) -> Str format!( " unconstrained fn compute_note_hash_and_nullifier( - contract_address: AztecAddress, + contract_address: dep::aztec::protocol_types::address::AztecAddress, nonce: Field, storage_slot: Field, note_type_id: Field, diff --git a/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs b/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs new file mode 100644 index 000000000000..4401c867df96 --- /dev/null +++ b/noir/noir-repo/aztec_macros/src/transforms/contract_interface.rs @@ -0,0 +1,326 @@ +use noirc_frontend::{ + graph::CrateId, + macros_api::{FileId, HirContext, HirExpression, HirLiteral, HirStatement}, + parse_program, + parser::SortedModule, + NoirFunction, Type, UnresolvedTypeData, +}; + +use crate::utils::{ + constants::SELECTOR_PLACEHOLDER, + errors::AztecMacroError, + hir_utils::{collect_crate_structs, get_contract_module_data, signature_of_type}, +}; + +// Generates the stubs for contract functions as low level calls using CallInterface, turning +// #[aztec(public)] // also private +// fn a_function(first_arg: Field, second_arg: Struct, third_arg: [Field; 4]) -> Field { +// ... +// } +// +// into +// +// pub fn a_function(self, first_arg: Field, second_arg: Struct, third_arg: [Field; 4]) -> PublicCallInterface { +// let mut args_acc: [Field] = &[]; +// args_acc = args_acc.append(first_arg.serialize().as_slice()); +// args_acc = args_acc.append(second_arg.serialize().as_slice()); +// let hash_third_arg = third_arg.map(|x: Field| x.serialize()); +// for i in 0..third_arg.len() { +// args_acc = args_acc.append(third_arg[i].serialize().as_slice()); +// } +// let args_hash = dep::aztec::hash::hash_args(args_acc); +// assert(args_hash == dep::aztec::oracle::arguments::pack_arguments(args_acc)); +// PublicCallInterface { +// target_contract: self.target_contract, +// selector: FunctionSelector::from_signature("SELECTOR_PLACEHOLDER"), +// args_hash +// } +// } +// +// The selector placeholder has to be replaced with the actual function signature after type checking in the next macro pass +pub fn stub_function(aztec_visibility: &str, func: &NoirFunction) -> String { + let fn_name = func.name().to_string(); + let fn_parameters = func + .parameters() + .iter() + .map(|param| { + format!( + "{}: {}", + param.pattern.name_ident().0.contents, + param.typ.to_string().replace("plain::", "") + ) + }) + .collect::>() + .join(", "); + let fn_return_type: noirc_frontend::UnresolvedType = func.return_type(); + + let fn_selector = format!("dep::aztec::protocol_types::abis::function_selector::FunctionSelector::from_signature(\"{}\")", SELECTOR_PLACEHOLDER); + + let parameters = func.parameters(); + let is_void = if matches!(fn_return_type.typ, UnresolvedTypeData::Unit) { "Void" } else { "" }; + let return_type_hint = if is_void == "Void" { + "".to_string() + } else { + format!("<{}>", fn_return_type.typ.to_string().replace("plain::", "")) + }; + let call_args = parameters + .iter() + .map(|arg| { + let param_name = arg.pattern.name_ident().0.contents.clone(); + match &arg.typ.typ { + UnresolvedTypeData::Array(_, typ) => { + format!( + "let hash_{0} = {0}.map(|x: {1}| x.serialize()); + for i in 0..{0}.len() {{ + args_acc = args_acc.append(hash_{0}[i].as_slice()); + }}\n", + param_name, typ.typ + ) + } + _ => { + format!("args_acc = args_acc.append({}.serialize().as_slice());\n", param_name) + } + } + }) + .collect::>() + .join(""); + if aztec_visibility != "Avm" { + let args_hash = if !parameters.is_empty() { + format!( + "let mut args_acc: [Field] = &[]; + {} + let args_hash = dep::aztec::hash::hash_args(args_acc); + assert(args_hash == dep::aztec::oracle::arguments::pack_arguments(args_acc));", + call_args + ) + } else { + "let args_hash = 0;".to_string() + }; + + let fn_body = format!( + "{} + dep::aztec::context::{}{}CallInterface {{ + target_contract: self.target_contract, + selector: {}, + args_hash, + }}", + args_hash, aztec_visibility, is_void, fn_selector, + ); + format!( + "pub fn {}(self, {}) -> dep::aztec::context::{}{}CallInterface{} {{ + {} + }}", + fn_name, fn_parameters, aztec_visibility, is_void, return_type_hint, fn_body + ) + } else { + let args = format!( + "let mut args_acc: [Field] = &[]; + {} + ", + call_args + ); + let fn_body = format!( + "{} + dep::aztec::context::Avm{}CallInterface {{ + target_contract: self.target_contract, + selector: {}, + args: args_acc, + }}", + args, is_void, fn_selector, + ); + format!( + "pub fn {}(self, {}) -> dep::aztec::context::Avm{}CallInterface{} {{ + {} + }}", + fn_name, fn_parameters, is_void, return_type_hint, fn_body + ) + } +} + +// Generates the contract interface as a struct with an `at` function that holds the stubbed functions and provides +// them with a target contract address. The struct has the same name as the contract (which is technically a module) +// so imports look nice. The `at` function is also exposed as a contract library method for external use. +pub fn generate_contract_interface( + module: &mut SortedModule, + module_name: &str, + stubs: &[String], +) -> Result<(), AztecMacroError> { + let contract_interface = format!( + " + struct {0} {{ + target_contract: dep::aztec::protocol_types::address::AztecAddress + }} + + impl {0} {{ + {1} + + pub fn at( + target_contract: dep::aztec::protocol_types::address::AztecAddress + ) -> Self {{ + Self {{ target_contract }} + }} + }} + + #[contract_library_method] + pub fn at( + target_contract: dep::aztec::protocol_types::address::AztecAddress + ) -> {0} {{ + {0} {{ target_contract }} + }} + ", + module_name, + stubs.join("\n"), + ); + + let (contract_interface_ast, errors) = parse_program(&contract_interface); + if !errors.is_empty() { + dbg!(errors); + return Err(AztecMacroError::CouldNotGenerateContractInterface { secondary_message: Some("Failed to parse Noir macro code during contract interface generation. This is either a bug in the compiler or the Noir macro code".to_string()), }); + } + + let mut contract_interface_ast = contract_interface_ast.into_sorted(); + module.types.push(contract_interface_ast.types.pop().unwrap()); + module.impls.push(contract_interface_ast.impls.pop().unwrap()); + module.functions.push(contract_interface_ast.functions.pop().unwrap()); + + Ok(()) +} + +fn compute_fn_signature(fn_name: &str, parameters: &[Type]) -> String { + format!( + "{}({})", + fn_name, + parameters.iter().map(signature_of_type).collect::>().join(",") + ) +} + +// Updates the function signatures in the contract interface with the actual ones, replacing the placeholder. +// This is done by locating the contract interface struct, its functions (stubs) and assuming the last statement of each +// is the constructor for a CallInterface. This constructor has a selector field that holds a +// FunctionSelector::from_signature function that receives the signature as a string literal. +pub fn update_fn_signatures_in_contract_interface( + crate_id: &CrateId, + context: &mut HirContext, +) -> Result<(), (AztecMacroError, FileId)> { + if let Some((name, _, file_id)) = get_contract_module_data(context, crate_id) { + let maybe_interface_struct = + collect_crate_structs(crate_id, context).iter().find_map(|struct_id| { + let r#struct = context.def_interner.get_struct(*struct_id); + if r#struct.borrow().name.0.contents == name { + Some(r#struct) + } else { + None + } + }); + + if let Some(interface_struct) = maybe_interface_struct { + let methods = context.def_interner.get_struct_methods(interface_struct.borrow().id); + + for func_id in methods.iter().flat_map(|methods| methods.direct.iter()) { + let name = context.def_interner.function_name(func_id); + let fn_parameters = &context.def_interner.function_meta(func_id).parameters.clone(); + + if name == "at" { + continue; + } + + let fn_signature = compute_fn_signature( + name, + &fn_parameters + .iter() + .skip(1) + .map(|(_, typ, _)| typ.clone()) + .collect::>(), + ); + let hir_func = context.def_interner.function(func_id).block(&context.def_interner); + let call_interface_constructor_statement = context.def_interner.statement( + hir_func + .statements() + .last() + .ok_or((AztecMacroError::AztecDepNotFound, file_id))?, + ); + let call_interface_constructor_expression = + match call_interface_constructor_statement { + HirStatement::Expression(expression_id) => { + match context.def_interner.expression(&expression_id) { + HirExpression::Constructor(hir_constructor_expression) => { + Ok(hir_constructor_expression) + } + _ => Err(( + AztecMacroError::CouldNotGenerateContractInterface { + secondary_message: Some( + "CallInterface constructor statement must be a constructor expression" + .to_string(), + ), + }, + file_id, + )), + } + } + _ => Err(( + AztecMacroError::CouldNotGenerateContractInterface { + secondary_message: Some( + "CallInterface constructor statement must be an expression" + .to_string(), + ), + }, + file_id, + )), + }?; + let (_, function_selector_expression_id) = + call_interface_constructor_expression.fields[1]; + let function_selector_expression = + context.def_interner.expression(&function_selector_expression_id); + + let current_fn_signature_expression_id = match function_selector_expression { + HirExpression::Call(call_expr) => Ok(call_expr.arguments[0]), + _ => Err(( + AztecMacroError::CouldNotGenerateContractInterface { + secondary_message: Some( + "Function selector argument expression must be call expression" + .to_string(), + ), + }, + file_id, + )), + }?; + + let current_fn_signature_expression = + context.def_interner.expression(¤t_fn_signature_expression_id); + + match current_fn_signature_expression { + HirExpression::Literal(HirLiteral::Str(signature)) => { + if signature != SELECTOR_PLACEHOLDER { + Err(( + AztecMacroError::CouldNotGenerateContractInterface { + secondary_message: Some(format!( + "Function signature argument must be a placeholder: {}", + SELECTOR_PLACEHOLDER + )), + }, + file_id, + )) + } else { + Ok(()) + } + } + _ => Err(( + AztecMacroError::CouldNotAssignStorageSlots { + secondary_message: Some( + "Function signature argument must be a literal string".to_string(), + ), + }, + file_id, + )), + }?; + + context + .def_interner + .update_expression(current_fn_signature_expression_id, |expr| { + *expr = HirExpression::Literal(HirLiteral::Str(fn_signature)) + }); + } + } + } + Ok(()) +} diff --git a/noir/noir-repo/aztec_macros/src/transforms/events.rs b/noir/noir-repo/aztec_macros/src/transforms/events.rs index 4f2b70453dff..b77a5821b813 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/events.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/events.rs @@ -174,7 +174,7 @@ pub fn transform_events( crate_id: &CrateId, context: &mut HirContext, ) -> Result<(), (AztecMacroError, FileId)> { - for (_, struct_id) in collect_crate_structs(crate_id, context) { + for struct_id in collect_crate_structs(crate_id, context) { let attributes = context.def_interner.struct_attributes(&struct_id); if attributes.iter().any(|attr| is_custom_attribute(attr, "aztec(event)")) { transform_event(struct_id, &mut context.def_interner)?; diff --git a/noir/noir-repo/aztec_macros/src/transforms/mod.rs b/noir/noir-repo/aztec_macros/src/transforms/mod.rs index 5a454c751481..2a6fef7647fc 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/mod.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/mod.rs @@ -1,4 +1,5 @@ pub mod compute_note_hash_and_nullifier; +pub mod contract_interface; pub mod events; pub mod functions; pub mod note_interface; diff --git a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs index 0514155824e8..4b72759a5dba 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/note_interface.rs @@ -528,12 +528,12 @@ fn generate_note_properties_fn_source( .join(", "); format!( " - pub fn properties() -> {}Properties {{ - {}Properties {{ - {} + pub fn properties() -> {0}Properties {{ + {0}Properties {{ + {1} }} }}", - note_type, note_type, note_property_selectors + note_type, note_property_selectors ) .to_string() } @@ -623,7 +623,7 @@ pub fn inject_note_exports( crate_id: &CrateId, context: &mut HirContext, ) -> Result<(), (AztecMacroError, FileId)> { - if let Some((module_id, file_id)) = get_contract_module_data(context, crate_id) { + if let Some((_, module_id, file_id)) = get_contract_module_data(context, crate_id) { let notes = fetch_notes(context); for (_, note) in notes { diff --git a/noir/noir-repo/aztec_macros/src/transforms/storage.rs b/noir/noir-repo/aztec_macros/src/transforms/storage.rs index 0bfb39cbc713..9135be32443b 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/storage.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/storage.rs @@ -265,13 +265,13 @@ pub fn assign_storage_slots( context: &mut HirContext, ) -> Result<(), (AztecMacroError, FileId)> { let traits: Vec<_> = collect_traits(context); - if let Some((_, file_id)) = get_contract_module_data(context, crate_id) { + if let Some((_, _, file_id)) = get_contract_module_data(context, crate_id) { let maybe_storage_struct = - collect_crate_structs(crate_id, context).iter().find_map(|&(_, struct_id)| { - let r#struct = context.def_interner.get_struct(struct_id); - let attributes = context.def_interner.struct_attributes(&struct_id); + collect_crate_structs(crate_id, context).iter().find_map(|struct_id| { + let r#struct = context.def_interner.get_struct(*struct_id); + let attributes = context.def_interner.struct_attributes(struct_id); if attributes.iter().any(|attr| is_custom_attribute(attr, "aztec(storage)")) - && r#struct.borrow().id.krate().is_root() + && r#struct.borrow().id.krate() == *crate_id { Some(r#struct) } else { @@ -290,7 +290,11 @@ pub fn assign_storage_slots( let expr = context.def_interner.expression(&statement.unwrap().expression); match expr { HirExpression::Constructor(hir_constructor_expression) => { - Some(hir_constructor_expression) + if hir_constructor_expression.r#type.borrow().id.krate() == *crate_id { + Some(hir_constructor_expression) + } else { + None + } } _ => None, } diff --git a/noir/noir-repo/aztec_macros/src/utils/constants.rs b/noir/noir-repo/aztec_macros/src/utils/constants.rs index 464cd10e2c75..848cca0477d8 100644 --- a/noir/noir-repo/aztec_macros/src/utils/constants.rs +++ b/noir/noir-repo/aztec_macros/src/utils/constants.rs @@ -1,3 +1,4 @@ pub const FUNCTION_TREE_HEIGHT: u32 = 5; pub const MAX_CONTRACT_PRIVATE_FUNCTIONS: usize = 2_usize.pow(FUNCTION_TREE_HEIGHT); pub const SIGNATURE_PLACEHOLDER: &str = "SIGNATURE_PLACEHOLDER"; +pub const SELECTOR_PLACEHOLDER: &str = "SELECTOR_PLACEHOLDER"; diff --git a/noir/noir-repo/aztec_macros/src/utils/errors.rs b/noir/noir-repo/aztec_macros/src/utils/errors.rs index 5d3a61a51dce..4c5411dfe0f9 100644 --- a/noir/noir-repo/aztec_macros/src/utils/errors.rs +++ b/noir/noir-repo/aztec_macros/src/utils/errors.rs @@ -11,10 +11,12 @@ pub enum AztecMacroError { UnsupportedFunctionReturnType { span: Span, typ: UnresolvedTypeData }, UnsupportedStorageType { span: Option, typ: UnresolvedTypeData }, CouldNotAssignStorageSlots { secondary_message: Option }, + CouldNotImplementComputeNoteHashAndNullifier { secondary_message: Option }, CouldNotImplementNoteInterface { span: Option, secondary_message: Option }, MultipleStorageDefinitions { span: Option }, CouldNotExportStorageLayout { span: Option, secondary_message: Option }, CouldNotExportFunctionAbi { span: Option, secondary_message: Option }, + CouldNotGenerateContractInterface { secondary_message: Option }, EventError { span: Span, message: String }, UnsupportedAttributes { span: Span, secondary_message: Option }, } @@ -23,7 +25,7 @@ impl From for MacroError { fn from(err: AztecMacroError) -> Self { match err { AztecMacroError::AztecDepNotFound {} => 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/developers/debugging/aztecnr-errors#aztec-dependency-not-found-please-add-aztec-as-a-dependency-in-your-nargotoml".to_owned(), + primary_message: "Aztec dependency not found. Please add aztec as a dependency in your Nargo.toml. For more information go to https://docs.aztec.network/developers/debugging/aztecnr-errors#aztec-dependency-not-found-please-add-aztec-as-a-dependency-in-your-nargotoml".to_owned(), secondary_message: None, span: None, }, @@ -52,6 +54,11 @@ impl From for MacroError { secondary_message, span: None, }, + AztecMacroError::CouldNotImplementComputeNoteHashAndNullifier { secondary_message } => MacroError { + primary_message: "Could not implement compute_note_hash_and_nullifier automatically, please provide an implementation".to_string(), + secondary_message, + span: None, + }, AztecMacroError::CouldNotImplementNoteInterface { span, secondary_message } => MacroError { primary_message: "Could not implement automatic methods for note, please provide an implementation of the NoteInterface trait".to_string(), secondary_message, @@ -72,6 +79,11 @@ impl From for MacroError { secondary_message, span, }, + AztecMacroError::CouldNotGenerateContractInterface { secondary_message } => MacroError { + primary_message: "Could not generate contract interface".to_string(), + secondary_message, + span: None + }, AztecMacroError::EventError { span, message } => MacroError { primary_message: message, secondary_message: None, diff --git a/noir/noir-repo/aztec_macros/src/utils/hir_utils.rs b/noir/noir-repo/aztec_macros/src/utils/hir_utils.rs index c4414e6419b9..ae895d2075c2 100644 --- a/noir/noir-repo/aztec_macros/src/utils/hir_utils.rs +++ b/noir/noir-repo/aztec_macros/src/utils/hir_utils.rs @@ -7,43 +7,32 @@ use noirc_frontend::{ resolution::{path_resolver::StandardPathResolver, resolver::Resolver}, type_check::type_check_func, }, - macros_api::{FileId, HirContext, ModuleDefId, StructId}, + macros_api::{FileId, HirContext, MacroError, ModuleDefId, StructId}, node_interner::{FuncId, TraitId}, ItemVisibility, LetStatement, NoirFunction, Shared, Signedness, StructType, Type, }; use super::ast_utils::is_custom_attribute; -pub fn collect_crate_structs(crate_id: &CrateId, context: &HirContext) -> Vec<(String, StructId)> { +pub fn collect_crate_structs(crate_id: &CrateId, context: &HirContext) -> Vec { context .def_map(crate_id) - .expect("ICE: Missing crate in def_map") - .modules() - .iter() - .flat_map(|(_, module)| { - module.type_definitions().filter_map(move |typ| { - if let ModuleDefId::TypeId(struct_id) = typ { - let module_id = struct_id.module_id(); - let path = - context.fully_qualified_struct_path(context.root_crate_id(), struct_id); - let path = if path.contains("::") { - let prefix = if &module_id.krate == context.root_crate_id() { - "crate" + .map(|def_map| { + def_map + .modules() + .iter() + .flat_map(|(_, module)| { + module.type_definitions().filter_map(move |typ| { + if let ModuleDefId::TypeId(struct_id) = typ { + Some(struct_id) } else { - "dep" - }; - format!("{}::{}", prefix, path) - } else { - path - }; - - Some((path, struct_id)) - } else { - None - } - }) + None + } + }) + }) + .collect() }) - .collect() + .unwrap_or_default() } pub fn collect_crate_functions(crate_id: &CrateId, context: &HirContext) -> Vec { @@ -96,22 +85,48 @@ pub fn signature_of_type(typ: &Type) -> String { let fields = vecmap(types, signature_of_type); format!("({})", fields.join(",")) } + Type::String(len_typ) => { + if let Type::Constant(len) = **len_typ { + format!("str<{len}>") + } else { + unimplemented!( + "Cannot generate signature for string with length type {:?}", + len_typ + ) + } + } + Type::MutableReference(typ) => signature_of_type(typ), _ => unimplemented!("Cannot generate signature for type {:?}", typ), } } -// Fetches the name of all structs tagged as #[aztec(note)] in a given crate +// Fetches the name of all structs tagged as #[aztec(note)] in a given crate, avoiding +// contract dependencies that are just there for their interfaces. pub fn fetch_crate_notes( context: &HirContext, crate_id: &CrateId, ) -> Vec<(String, Shared)> { collect_crate_structs(crate_id, context) .iter() - .filter_map(|(path, struct_id)| { + .filter_map(|struct_id| { let r#struct = context.def_interner.get_struct(*struct_id); let attributes = context.def_interner.struct_attributes(struct_id); if attributes.iter().any(|attr| is_custom_attribute(attr, "aztec(note)")) { - Some((path.clone(), r#struct)) + let module_id = struct_id.module_id(); + + fully_qualified_note_path(context, *struct_id).map(|path| { + let path = if path.contains("::") { + let prefix = if &module_id.krate == context.root_crate_id() { + "crate" + } else { + "dep" + }; + format!("{}::{}", prefix, path) + } else { + path + }; + (path.clone(), r#struct) + }) } else { None } @@ -127,23 +142,24 @@ pub fn fetch_notes(context: &HirContext) -> Vec<(String, Shared)> { pub fn get_contract_module_data( context: &mut HirContext, crate_id: &CrateId, -) -> Option<(LocalModuleId, FileId)> { +) -> Option<(String, LocalModuleId, FileId)> { + let def_map = context.def_map(crate_id).expect("ICE: Missing crate in def_map"); // We first fetch modules in this crate which correspond to contracts, along with their file id. - let contract_module_file_ids: Vec<(LocalModuleId, FileId)> = context - .def_map(crate_id) - .expect("ICE: Missing crate in def_map") + let contract_module_file_ids: Vec<(String, LocalModuleId, FileId)> = def_map .modules() .iter() .filter(|(_, module)| module.is_contract) - .map(|(idx, module)| (LocalModuleId(idx), module.location.file)) + .map(|(idx, module)| { + (def_map.get_module_path(idx, module.parent), LocalModuleId(idx), module.location.file) + }) .collect(); - // If the current crate does not contain a contract module we simply skip it. More than 1 contract in a crate is forbidden by the compiler + // If the current crate does not contain a contract module we simply skip it. if contract_module_file_ids.is_empty() { return None; } - Some(contract_module_file_ids[0]) + Some(contract_module_file_ids[0].clone()) } pub fn inject_fn( @@ -153,7 +169,7 @@ pub fn inject_fn( location: Location, module_id: LocalModuleId, file_id: FileId, -) { +) -> Result<(), MacroError> { let func_id = context.def_interner.push_empty_fn(); context.def_interner.push_function( func_id, @@ -164,12 +180,11 @@ pub fn inject_fn( context.def_map_mut(crate_id).unwrap().modules_mut()[module_id.0] .declare_function(func.name_ident().clone(), ItemVisibility::Public, func_id) - .unwrap_or_else(|_| { - panic!( - "Failed to declare autogenerated {} function, likely due to a duplicate definition", - func.name() - ) - }); + .map_err(|err| MacroError { + primary_message: format!("Failed to declare autogenerated {} function", func.name()), + secondary_message: Some(format!("Duplicate definition found {}", err.0)), + span: None, + })?; let def_maps = &mut context.def_maps; @@ -183,7 +198,17 @@ pub fn inject_fn( context.def_interner.push_fn_meta(meta, func_id); context.def_interner.update_fn(func_id, hir_func); - type_check_func(&mut context.def_interner, func_id); + let errors = type_check_func(&mut context.def_interner, func_id); + + if !errors.is_empty() { + return Err(MacroError { + primary_message: "Failed to type check autogenerated function".to_owned(), + secondary_message: Some(errors.iter().map(|err| err.to_string()).collect::()), + span: None, + }); + } + + Ok(()) } pub fn inject_global( @@ -224,3 +249,63 @@ pub fn inject_global( let statement_id = context.def_interner.get_global(global_id).let_statement; context.def_interner.replace_statement(statement_id, hir_stmt); } + +pub fn fully_qualified_note_path(context: &HirContext, note_id: StructId) -> Option { + let module_id = note_id.module_id(); + let child_id = module_id.local_id.0; + let def_map = + context.def_map(&module_id.krate).expect("The local crate should be analyzed already"); + + let module = context.module(module_id); + + let module_path = def_map.get_module_path_with_separator(child_id, module.parent, "::"); + + if &module_id.krate == context.root_crate_id() { + Some(module_path) + } else { + find_non_contract_dependencies_bfs(context, context.root_crate_id(), &module_id.krate) + .map(|crates| crates.join("::") + "::" + &module_path) + } +} + +fn filter_contract_modules(context: &HirContext, crate_id: &CrateId) -> bool { + if let Some(def_map) = context.def_map(crate_id) { + !def_map.modules().iter().any(|(_, module)| module.is_contract) + } else { + true + } +} + +fn find_non_contract_dependencies_bfs( + context: &HirContext, + crate_id: &CrateId, + target_crate_id: &CrateId, +) -> Option> { + context.crate_graph[crate_id] + .dependencies + .iter() + .filter(|dep| filter_contract_modules(context, &dep.crate_id)) + .find_map(|dep| { + if &dep.crate_id == target_crate_id { + Some(vec![dep.name.to_string()]) + } else { + None + } + }) + .or_else(|| { + context.crate_graph[crate_id] + .dependencies + .iter() + .filter(|dep| filter_contract_modules(context, &dep.crate_id)) + .find_map(|dep| { + if let Some(mut path) = + find_non_contract_dependencies_bfs(context, &dep.crate_id, target_crate_id) + { + path.insert(0, dep.name.to_string()); + Some(path) + } else { + None + } + }) + }) +} diff --git a/noir/noir-repo/compiler/noirc_driver/src/contract.rs b/noir/noir-repo/compiler/noirc_driver/src/contract.rs index a33a9b809d3a..d6c3dc6205d4 100644 --- a/noir/noir-repo/compiler/noirc_driver/src/contract.rs +++ b/noir/noir-repo/compiler/noirc_driver/src/contract.rs @@ -53,7 +53,7 @@ pub struct ContractFunction { )] pub bytecode: Program, - pub debug: DebugInfo, + pub debug: 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_driver/src/lib.rs b/noir/noir-repo/compiler/noirc_driver/src/lib.rs index 6fe447804840..8a554879e9f8 100644 --- a/noir/noir-repo/compiler/noirc_driver/src/lib.rs +++ b/noir/noir-repo/compiler/noirc_driver/src/lib.rs @@ -430,7 +430,8 @@ fn compile_contract_inner( } if errors.is_empty() { - let debug_infos: Vec<_> = functions.iter().map(|function| function.debug.clone()).collect(); + let debug_infos: Vec<_> = + functions.iter().flat_map(|function| function.debug.clone()).collect(); let file_map = filter_relevant_files(&debug_infos, &context.file_manager); let out_structs = contract @@ -547,13 +548,8 @@ pub fn compile_no_check( Ok(CompiledProgram { hash, - // TODO(https://github.com/noir-lang/noir/issues/4428) program, - // TODO(https://github.com/noir-lang/noir/issues/4428) - // Debug info is only relevant for errors at execution time which is not yet supported - // The CompileProgram `debug` field is used in multiple places and is better - // left to be updated once execution of multiple ACIR functions is enabled - debug: debug[0].clone(), + debug, abi, file_map, noir_version: NOIR_ARTIFACT_VERSION_STRING.to_string(), diff --git a/noir/noir-repo/compiler/noirc_driver/src/program.rs b/noir/noir-repo/compiler/noirc_driver/src/program.rs index 9ffd2d70dda9..ed7ddb29f59c 100644 --- a/noir/noir-repo/compiler/noirc_driver/src/program.rs +++ b/noir/noir-repo/compiler/noirc_driver/src/program.rs @@ -24,7 +24,7 @@ pub struct CompiledProgram { )] pub program: Program, pub abi: noirc_abi::Abi, - pub debug: DebugInfo, + pub debug: Vec, pub file_map: BTreeMap, pub warnings: Vec, /// Names of the functions in the program. These are used for more informative debugging and benchmarking. diff --git a/noir/noir-repo/compiler/noirc_errors/src/debug_info.rs b/noir/noir-repo/compiler/noirc_errors/src/debug_info.rs index 09117bdc3b78..54e2521e413a 100644 --- a/noir/noir-repo/compiler/noirc_errors/src/debug_info.rs +++ b/noir/noir-repo/compiler/noirc_errors/src/debug_info.rs @@ -46,6 +46,49 @@ pub type DebugVariables = BTreeMap; pub type DebugFunctions = BTreeMap; pub type DebugTypes = BTreeMap; +#[derive(Default, Debug, Clone, Deserialize, Serialize)] +pub struct ProgramDebugInfo { + pub debug_infos: Vec, +} + +impl ProgramDebugInfo { + pub fn serialize_compressed_base64_json( + debug_info: &ProgramDebugInfo, + s: S, + ) -> Result + where + S: Serializer, + { + let json_str = serde_json::to_string(debug_info).map_err(S::Error::custom)?; + + let mut encoder = DeflateEncoder::new(Vec::new(), Compression::default()); + encoder.write_all(json_str.as_bytes()).map_err(S::Error::custom)?; + let compressed_data = encoder.finish().map_err(S::Error::custom)?; + + let encoded_b64 = base64::prelude::BASE64_STANDARD.encode(compressed_data); + s.serialize_str(&encoded_b64) + } + + pub fn deserialize_compressed_base64_json<'de, D>( + deserializer: D, + ) -> Result + where + D: Deserializer<'de>, + { + let encoded_b64: String = Deserialize::deserialize(deserializer)?; + + let compressed_data = + base64::prelude::BASE64_STANDARD.decode(encoded_b64).map_err(D::Error::custom)?; + + let mut decoder = DeflateDecoder::new(&compressed_data[..]); + let mut decompressed_data = Vec::new(); + decoder.read_to_end(&mut decompressed_data).map_err(D::Error::custom)?; + + let json_str = String::from_utf8(decompressed_data).map_err(D::Error::custom)?; + serde_json::from_str(&json_str).map_err(D::Error::custom) + } +} + #[serde_as] #[derive(Default, Debug, Clone, Deserialize, Serialize)] pub struct DebugInfo { @@ -130,40 +173,4 @@ impl DebugInfo { counted_opcodes } - - pub fn serialize_compressed_base64_json( - debug_info: &DebugInfo, - s: S, - ) -> Result - where - S: Serializer, - { - let json_str = serde_json::to_string(debug_info).map_err(S::Error::custom)?; - - let mut encoder = DeflateEncoder::new(Vec::new(), Compression::default()); - encoder.write_all(json_str.as_bytes()).map_err(S::Error::custom)?; - let compressed_data = encoder.finish().map_err(S::Error::custom)?; - - let encoded_b64 = base64::prelude::BASE64_STANDARD.encode(compressed_data); - s.serialize_str(&encoded_b64) - } - - pub fn deserialize_compressed_base64_json<'de, D>( - deserializer: D, - ) -> Result - where - D: Deserializer<'de>, - { - let encoded_b64: String = Deserialize::deserialize(deserializer)?; - - let compressed_data = - base64::prelude::BASE64_STANDARD.decode(encoded_b64).map_err(D::Error::custom)?; - - let mut decoder = DeflateDecoder::new(&compressed_data[..]); - let mut decompressed_data = Vec::new(); - decoder.read_to_end(&mut decompressed_data).map_err(D::Error::custom)?; - - let json_str = String::from_utf8(decompressed_data).map_err(D::Error::custom)?; - serde_json::from_str(&json_str).map_err(D::Error::custom) - } } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index 36b5f8793cbc..ee047903743d 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -1,8 +1,11 @@ -use acvm::acir::{brillig::BlackBoxOp, BlackBoxFunc}; +use acvm::{ + acir::{brillig::BlackBoxOp, BlackBoxFunc}, + FieldElement, +}; use crate::brillig::brillig_ir::{ brillig_variable::{BrilligVariable, BrilligVector, SingleAddrVariable}, - BrilligContext, + BrilligBinaryOp, BrilligContext, }; /// Transforms SSA's black box function calls into the corresponding brillig instructions @@ -235,10 +238,17 @@ pub(crate) fn convert_black_box_call( ), BlackBoxFunc::BigIntAdd => { if let ( - [BrilligVariable::SingleAddr(lhs), BrilligVariable::SingleAddr(rhs)], - [BrilligVariable::SingleAddr(output)], + [BrilligVariable::SingleAddr(lhs), BrilligVariable::SingleAddr(lhs_modulus), BrilligVariable::SingleAddr(rhs), BrilligVariable::SingleAddr(rhs_modulus)], + [BrilligVariable::SingleAddr(output), BrilligVariable::SingleAddr(modulus_id)], ) = (function_arguments, function_results) { + prepare_bigint_output( + brillig_context, + lhs_modulus, + rhs_modulus, + output, + modulus_id, + ); brillig_context.black_box_op_instruction(BlackBoxOp::BigIntAdd { lhs: lhs.address, rhs: rhs.address, @@ -246,16 +256,23 @@ pub(crate) fn convert_black_box_call( }); } else { unreachable!( - "ICE: BigIntAdd expects two register arguments and one result register" + "ICE: BigIntAdd expects four register arguments and two result registers" ) } } BlackBoxFunc::BigIntSub => { if let ( - [BrilligVariable::SingleAddr(lhs), BrilligVariable::SingleAddr(rhs)], - [BrilligVariable::SingleAddr(output)], + [BrilligVariable::SingleAddr(lhs), BrilligVariable::SingleAddr(lhs_modulus), BrilligVariable::SingleAddr(rhs), BrilligVariable::SingleAddr(rhs_modulus)], + [BrilligVariable::SingleAddr(output), BrilligVariable::SingleAddr(modulus_id)], ) = (function_arguments, function_results) { + prepare_bigint_output( + brillig_context, + lhs_modulus, + rhs_modulus, + output, + modulus_id, + ); brillig_context.black_box_op_instruction(BlackBoxOp::BigIntSub { lhs: lhs.address, rhs: rhs.address, @@ -263,16 +280,23 @@ pub(crate) fn convert_black_box_call( }); } else { unreachable!( - "ICE: BigIntSub expects two register arguments and one result register" + "ICE: BigIntSub expects four register arguments and two result registers" ) } } BlackBoxFunc::BigIntMul => { if let ( - [BrilligVariable::SingleAddr(lhs), BrilligVariable::SingleAddr(rhs)], - [BrilligVariable::SingleAddr(output)], + [BrilligVariable::SingleAddr(lhs), BrilligVariable::SingleAddr(lhs_modulus), BrilligVariable::SingleAddr(rhs), BrilligVariable::SingleAddr(rhs_modulus)], + [BrilligVariable::SingleAddr(output), BrilligVariable::SingleAddr(modulus_id)], ) = (function_arguments, function_results) { + prepare_bigint_output( + brillig_context, + lhs_modulus, + rhs_modulus, + output, + modulus_id, + ); brillig_context.black_box_op_instruction(BlackBoxOp::BigIntMul { lhs: lhs.address, rhs: rhs.address, @@ -280,16 +304,23 @@ pub(crate) fn convert_black_box_call( }); } else { unreachable!( - "ICE: BigIntMul expects two register arguments and one result register" + "ICE: BigIntMul expects four register arguments and two result registers" ) } } BlackBoxFunc::BigIntDiv => { if let ( - [BrilligVariable::SingleAddr(lhs), BrilligVariable::SingleAddr(rhs)], - [BrilligVariable::SingleAddr(output)], + [BrilligVariable::SingleAddr(lhs), BrilligVariable::SingleAddr(lhs_modulus), BrilligVariable::SingleAddr(rhs), BrilligVariable::SingleAddr(rhs_modulus)], + [BrilligVariable::SingleAddr(output), BrilligVariable::SingleAddr(modulus_id)], ) = (function_arguments, function_results) { + prepare_bigint_output( + brillig_context, + lhs_modulus, + rhs_modulus, + output, + modulus_id, + ); brillig_context.black_box_op_instruction(BlackBoxOp::BigIntDiv { lhs: lhs.address, rhs: rhs.address, @@ -297,16 +328,20 @@ pub(crate) fn convert_black_box_call( }); } else { unreachable!( - "ICE: BigIntDiv expects two register arguments and one result register" + "ICE: BigIntDiv expects four register arguments and two result registers" ) } } BlackBoxFunc::BigIntFromLeBytes => { - if let ([inputs, modulus], [BrilligVariable::SingleAddr(output)]) = - (function_arguments, function_results) + if let ( + [inputs, modulus], + [BrilligVariable::SingleAddr(output), BrilligVariable::SingleAddr(_modulus_id)], + ) = (function_arguments, function_results) { let inputs_vector = convert_array_or_vector(brillig_context, inputs, bb_func); let modulus_vector = convert_array_or_vector(brillig_context, modulus, bb_func); + let output_id = brillig_context.get_new_bigint_id(); + brillig_context.const_instruction(*output, FieldElement::from(output_id as u128)); brillig_context.black_box_op_instruction(BlackBoxOp::BigIntFromLeBytes { inputs: inputs_vector.to_heap_vector(), modulus: modulus_vector.to_heap_vector(), @@ -314,23 +349,24 @@ pub(crate) fn convert_black_box_call( }); } else { unreachable!( - "ICE: BigIntFromLeBytes expects two register arguments and one result register" + "ICE: BigIntFromLeBytes expects a register and an array as arguments and two result registers" ) } } BlackBoxFunc::BigIntToLeBytes => { if let ( - [BrilligVariable::SingleAddr(input)], - [BrilligVariable::BrilligVector(result_vector)], + [BrilligVariable::SingleAddr(input), BrilligVariable::SingleAddr(_modulus)], + [result_array], ) = (function_arguments, function_results) { + let output = convert_array_or_vector(brillig_context, result_array, bb_func); brillig_context.black_box_op_instruction(BlackBoxOp::BigIntToLeBytes { input: input.address, - output: result_vector.to_heap_vector(), + output: output.to_heap_vector(), }); } else { unreachable!( - "ICE: BigIntToLeBytes expects one register argument and one array result" + "ICE: BigIntToLeBytes expects two register arguments and one array result" ) } } @@ -383,3 +419,30 @@ fn convert_array_or_vector( ), } } + +fn prepare_bigint_output( + brillig_context: &mut BrilligContext, + lhs_modulus: &SingleAddrVariable, + rhs_modulus: &SingleAddrVariable, + output: &SingleAddrVariable, + modulus_id: &SingleAddrVariable, +) { + // Check moduli + let condition = brillig_context.allocate_register(); + let condition_adr = SingleAddrVariable { address: condition, bit_size: 1 }; + brillig_context.binary_instruction( + *lhs_modulus, + *rhs_modulus, + condition_adr, + BrilligBinaryOp::Equals, + ); + brillig_context.codegen_constrain( + condition_adr, + Some("moduli should be identical in BigInt operation".to_string()), + ); + brillig_context.deallocate_register(condition); + // Set output id + let output_id = brillig_context.get_new_bigint_id(); + brillig_context.const_instruction(*output, FieldElement::from(output_id as u128)); + brillig_context.mov_instruction(modulus_id.address, lhs_modulus.address); +} diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index cf2501ab1c03..22407fc56959 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -5,7 +5,7 @@ use crate::brillig::brillig_ir::{ BrilligBinaryOp, BrilligContext, BRILLIG_MEMORY_ADDRESSING_BIT_SIZE, }; use crate::ssa::ir::dfg::CallStack; -use crate::ssa::ir::instruction::ConstrainError; +use crate::ssa::ir::instruction::{ConstrainError, UserDefinedConstrainError}; use crate::ssa::ir::{ basic_block::{BasicBlock, BasicBlockId}, dfg::DataFlowGraph, @@ -248,10 +248,15 @@ impl<'block> BrilligBlock<'block> { self.convert_ssa_binary(binary, dfg, result_var); } Instruction::Constrain(lhs, rhs, assert_message) => { - let assert_message = if let Some(error) = assert_message { + let (has_revert_data, static_assert_message) = if let Some(error) = assert_message { match error.as_ref() { - ConstrainError::Static(string) => Some(string.clone()), - ConstrainError::Dynamic(call_instruction) => { + ConstrainError::Intrinsic(string) => (false, Some(string.clone())), + ConstrainError::UserDefined(UserDefinedConstrainError::Static(string)) => { + (true, Some(string.clone())) + } + ConstrainError::UserDefined(UserDefinedConstrainError::Dynamic( + call_instruction, + )) => { let Instruction::Call { func, arguments } = call_instruction else { unreachable!("expected a call instruction") }; @@ -264,11 +269,11 @@ impl<'block> BrilligBlock<'block> { // Dynamic assert messages are handled in the generated function call. // We then don't need to attach one to the constrain instruction. - None + (false, None) } } } else { - None + (false, None) }; let condition = SingleAddrVariable { @@ -281,8 +286,12 @@ impl<'block> BrilligBlock<'block> { dfg, condition, ); - - self.brillig_context.constrain_instruction(condition, assert_message); + if has_revert_data { + self.brillig_context + .codegen_constrain_with_revert_data(condition, static_assert_message); + } else { + self.brillig_context.codegen_constrain(condition, static_assert_message); + } self.brillig_context.deallocate_single_addr(condition); } Instruction::Allocate => { @@ -670,7 +679,7 @@ impl<'block> BrilligBlock<'block> { BrilligBinaryOp::LessThanEquals, ); - self.brillig_context.constrain_instruction(condition, assert_message.clone()); + self.brillig_context.codegen_constrain(condition, assert_message.clone()); self.brillig_context.deallocate_single_addr(condition); self.brillig_context.deallocate_single_addr(left); self.brillig_context.deallocate_single_addr(right); @@ -802,7 +811,7 @@ impl<'block> BrilligBlock<'block> { ); self.brillig_context - .constrain_instruction(condition, Some("Array index out of bounds".to_owned())); + .codegen_constrain(condition, Some("Array index out of bounds".to_owned())); if should_deallocate_size { self.brillig_context.deallocate_single_addr(size_as_register); @@ -1503,10 +1512,8 @@ impl<'block> BrilligBlock<'block> { condition, BrilligBinaryOp::LessThanEquals, ); - self.brillig_context.constrain_instruction( - condition, - Some("attempt to add with overflow".to_string()), - ); + self.brillig_context + .codegen_constrain(condition, Some("attempt to add with overflow".to_string())); self.brillig_context.deallocate_single_addr(condition); } (BrilligBinaryOp::Sub, false) => { @@ -1519,7 +1526,7 @@ impl<'block> BrilligBlock<'block> { condition, BrilligBinaryOp::LessThanEquals, ); - self.brillig_context.constrain_instruction( + self.brillig_context.codegen_constrain( condition, Some("attempt to subtract with overflow".to_string()), ); @@ -1549,7 +1556,7 @@ impl<'block> BrilligBlock<'block> { BrilligBinaryOp::UnsignedDiv, ); ctx.binary_instruction(division, left, condition, BrilligBinaryOp::Equals); - ctx.constrain_instruction( + ctx.codegen_constrain( condition, Some("attempt to multiply with overflow".to_string()), ); @@ -1778,7 +1785,7 @@ pub(crate) fn type_of_binary_operation(lhs_type: &Type, rhs_type: &Type) -> Type (Type::Numeric(lhs_type), Type::Numeric(rhs_type)) => { assert_eq!( lhs_type, rhs_type, - "lhs and rhs types in a binary operation are always the same" + "lhs and rhs types in a binary operation are always the same but got {lhs_type} and {rhs_type}" ); Type::Numeric(*lhs_type) } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index e5c731be6798..7e37e1da434a 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -86,6 +86,8 @@ pub(crate) struct BrilligContext { next_section: usize, /// IR printer debug_show: DebugShow, + /// Counter for generating bigint ids in unconstrained functions + bigint_new_id: u32, } impl BrilligContext { @@ -98,9 +100,15 @@ impl BrilligContext { section_label: 0, next_section: 1, debug_show: DebugShow::new(enable_debug_trace), + bigint_new_id: 0, } } + pub(crate) fn get_new_bigint_id(&mut self) -> u32 { + let result = self.bigint_new_id; + self.bigint_new_id += 1; + result + } /// Adds a brillig instruction to the brillig byte code fn push_opcode(&mut self, opcode: BrilligOpcode) { self.obj.push_opcode(opcode); @@ -140,7 +148,7 @@ pub(crate) mod tests { &self, _public_key_x: &FieldElement, _public_key_y: &FieldElement, - _signature: &[u8], + _signature: &[u8; 64], _message: &[u8], ) -> Result { Ok(true) @@ -262,7 +270,7 @@ pub(crate) mod tests { // uses unresolved jumps which requires a block to be constructed in SSA and // we don't need this for Brillig IR tests context.push_opcode(BrilligOpcode::JumpIf { condition: r_equality, location: 8 }); - context.push_opcode(BrilligOpcode::Trap); + context.push_opcode(BrilligOpcode::Trap { revert_data_offset: 0, revert_data_size: 0 }); context.stop_instruction(); diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs index 8ce15ba4e73f..8a4f469f5c93 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs @@ -4,7 +4,7 @@ use std::collections::{BTreeMap, HashMap}; use crate::ssa::ir::dfg::CallStack; /// Represents a parameter or a return value of an entry point function. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] pub(crate) enum BrilligParameter { /// A single address parameter or return value. Holds the bit size of the parameter. SingleAddr(u32), @@ -17,7 +17,7 @@ pub(crate) enum BrilligParameter { /// The result of compiling and linking brillig artifacts. /// This is ready to run bytecode with attached metadata. -#[derive(Debug)] +#[derive(Debug, Default)] pub(crate) struct GeneratedBrillig { pub(crate) byte_code: Vec, pub(crate) locations: BTreeMap, diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_control_flow.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_control_flow.rs index 116eaa5103fb..f8f39f03df4d 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_control_flow.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_control_flow.rs @@ -138,4 +138,48 @@ impl BrilligContext { self.enter_section(end_section); } + + /// Emits brillig bytecode to jump to a trap condition if `condition` + /// is false. The trap will include the given message as revert data. + pub(crate) fn codegen_constrain_with_revert_data( + &mut self, + condition: SingleAddrVariable, + assert_message: Option, + ) { + assert!(condition.bit_size == 1); + + self.codegen_if_not(condition.address, |ctx| { + let (revert_data_offset, revert_data_size) = + if let Some(assert_message) = assert_message { + let bytes = assert_message.as_bytes(); + for (i, byte) in bytes.iter().enumerate() { + ctx.const_instruction( + SingleAddrVariable::new(MemoryAddress(i), 8), + (*byte as usize).into(), + ); + } + (0, bytes.len()) + } else { + (0, 0) + }; + ctx.trap_instruction(revert_data_offset, revert_data_size); + }); + } + + /// Emits brillig bytecode to jump to a trap condition if `condition` + /// is false. + pub(crate) fn codegen_constrain( + &mut self, + condition: SingleAddrVariable, + assert_message: Option, + ) { + assert!(condition.bit_size == 1); + + self.codegen_if_not(condition.address, |ctx| { + ctx.trap_instruction(0, 0); + if let Some(assert_message) = assert_message { + ctx.obj.add_assert_message_to_last_opcode(assert_message); + } + }); + } } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index 4ca1144b6a49..41a6d1873e48 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -113,10 +113,14 @@ impl DebugShow { DebugShow { enable_debug_trace } } - /// Emits brillig bytecode to jump to a trap condition if `condition` - /// is false. - pub(crate) fn constrain_instruction(&self, condition: MemoryAddress) { - debug_println!(self.enable_debug_trace, " ASSERT {} != 0", condition); + /// Emits a `trap` instruction. + pub(crate) fn trap_instruction(&self, revert_data_offset: usize, revert_data_size: usize) { + debug_println!( + self.enable_debug_trace, + " TRAP {}..{}", + revert_data_offset, + revert_data_offset + revert_data_size + ); } /// Emits a `mov` instruction. diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs index fe3c5e0bb9c1..88cf987325d6 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs @@ -23,6 +23,7 @@ impl BrilligContext { section_label: 0, next_section: 1, debug_show: DebugShow::new(false), + bigint_new_id: 0, }; context.codegen_entry_point(&arguments, &return_parameters); diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs index f305eb81b01e..901ccc58036f 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs @@ -215,29 +215,6 @@ impl BrilligContext { ); } - /// Emits brillig bytecode to jump to a trap condition if `condition` - /// is false. - pub(crate) fn constrain_instruction( - &mut self, - condition: SingleAddrVariable, - assert_message: Option, - ) { - self.debug_show.constrain_instruction(condition.address); - - assert!(condition.bit_size == 1); - - let (next_section, next_label) = self.reserve_next_section_label(); - self.add_unresolved_jump( - BrilligOpcode::JumpIf { condition: condition.address, 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_section(next_section); - } - /// Adds a unresolved `Jump` to the bytecode. fn add_unresolved_jump( &mut self, @@ -488,6 +465,12 @@ impl BrilligContext { offset, }); } + + pub(super) fn trap_instruction(&mut self, revert_data_offset: usize, revert_data_size: usize) { + self.debug_show.trap_instruction(revert_data_offset, revert_data_size); + + self.push_opcode(BrilligOpcode::Trap { revert_data_offset, revert_data_size }); + } } /// Type to encapsulate the binary operation types in Brillig diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs index ce4a9bbe9f11..760340f1a881 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs @@ -14,7 +14,9 @@ use crate::{ errors::{RuntimeError, SsaReport}, }; use acvm::acir::{ - circuit::{Circuit, ExpressionWidth, Program as AcirProgram, PublicInputs}, + circuit::{ + brillig::BrilligBytecode, Circuit, ExpressionWidth, Program as AcirProgram, PublicInputs, + }, native_types::Witness, }; @@ -35,14 +37,16 @@ pub mod ssa_gen; /// Optimize the given program by converting it into SSA /// form and performing optimizations there. When finished, -/// convert the final SSA into ACIR and return it. +/// convert the final SSA into an ACIR program and return it. +/// An ACIR program is made up of both ACIR functions +/// and Brillig functions for unconstrained execution. pub(crate) fn optimize_into_acir( program: Program, print_passes: bool, print_brillig_trace: bool, force_brillig_output: bool, print_timings: bool, -) -> Result, RuntimeError> { +) -> Result<(Vec, Vec), RuntimeError> { let abi_distinctness = program.return_distinctness; let ssa_gen_span = span!(Level::TRACE, "ssa_generation"); @@ -99,6 +103,18 @@ pub struct SsaProgramArtifact { } impl SsaProgramArtifact { + fn new(unconstrained_functions: Vec) -> Self { + let program = AcirProgram { functions: Vec::default(), unconstrained_functions }; + Self { + program, + debug: Vec::default(), + warnings: Vec::default(), + main_input_witnesses: Vec::default(), + main_return_witnesses: Vec::default(), + names: Vec::default(), + } + } + 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); @@ -130,7 +146,7 @@ pub fn create_program( let func_sigs = program.function_signatures.clone(); let recursive = program.recursive; - let generated_acirs = optimize_into_acir( + let (generated_acirs, generated_brillig) = optimize_into_acir( program, enable_ssa_logging, enable_brillig_logging, @@ -143,7 +159,7 @@ pub fn create_program( "The generated ACIRs should match the supplied function signatures" ); - let mut program_artifact = SsaProgramArtifact::default(); + let mut program_artifact = SsaProgramArtifact::new(generated_brillig); // 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) { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 775571f4a413..b94e02e51199 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -1261,7 +1261,8 @@ impl AcirContext { let modulus = self.big_int_ctx.modulus(bigint.modulus_id()); let bytes_len = ((modulus - BigUint::from(1_u32)).bits() - 1) / 8 + 1; output_count = bytes_len as usize; - (field_inputs, vec![FieldElement::from(bytes_len as u128)]) + assert!(bytes_len == 32); + (field_inputs, vec![]) } BlackBoxFunc::BigIntFromLeBytes => { let invalid_input = "ICE - bigint operation requires 2 inputs"; @@ -1463,6 +1464,7 @@ impl AcirContext { id } + // TODO: Delete this method once we remove the `Brillig` opcode pub(crate) fn brillig( &mut self, predicate: AcirVar, @@ -1553,6 +1555,105 @@ impl AcirContext { Ok(outputs_var) } + #[allow(clippy::too_many_arguments)] + pub(crate) fn brillig_call( + &mut self, + predicate: AcirVar, + generated_brillig: &GeneratedBrillig, + inputs: Vec, + outputs: Vec, + attempt_execution: bool, + unsafe_return_values: bool, + brillig_function_index: u32, + ) -> Result, RuntimeError> { + let brillig_inputs = try_vecmap(inputs, |i| -> Result<_, InternalError> { + match i { + AcirValue::Var(var, _) => Ok(BrilligInputs::Single(self.var_to_expression(var)?)), + AcirValue::Array(vars) => { + let mut var_expressions: Vec = Vec::new(); + for var in vars { + self.brillig_array_input(&mut var_expressions, var)?; + } + Ok(BrilligInputs::Array(var_expressions)) + } + AcirValue::DynamicArray(AcirDynamicArray { block_id, .. }) => { + Ok(BrilligInputs::MemoryArray(block_id)) + } + } + })?; + + // Optimistically try executing the brillig now, if we can complete execution they just return the results. + // This is a temporary measure pending SSA optimizations being applied to Brillig which would remove constant-input opcodes (See #2066) + // + // We do _not_ want to do this in the situation where the `main` function is unconstrained, as if execution succeeds + // the entire program will be replaced with witness constraints to its outputs. + if attempt_execution { + if let Some(brillig_outputs) = + self.execute_brillig(&generated_brillig.byte_code, &brillig_inputs, &outputs) + { + return Ok(brillig_outputs); + } + } + + // Otherwise we must generate ACIR for it and execute at runtime. + let mut brillig_outputs = Vec::new(); + let outputs_var = vecmap(outputs, |output| match output { + AcirType::NumericType(_) => { + let witness_index = self.acir_ir.next_witness_index(); + brillig_outputs.push(BrilligOutputs::Simple(witness_index)); + let var = self.add_data(AcirVarData::Witness(witness_index)); + AcirValue::Var(var, output.clone()) + } + AcirType::Array(element_types, size) => { + let (acir_value, witnesses) = self.brillig_array_output(&element_types, size); + brillig_outputs.push(BrilligOutputs::Array(witnesses)); + acir_value + } + }); + let predicate = self.var_to_expression(predicate)?; + + self.acir_ir.brillig_call( + Some(predicate), + generated_brillig, + brillig_inputs, + brillig_outputs, + brillig_function_index, + ); + + fn range_constraint_value( + context: &mut AcirContext, + value: &AcirValue, + ) -> Result<(), RuntimeError> { + match value { + AcirValue::Var(var, typ) => { + let numeric_type = match typ { + AcirType::NumericType(numeric_type) => numeric_type, + _ => unreachable!("`AcirValue::Var` may only hold primitive values"), + }; + context.range_constrain_var(*var, numeric_type, None)?; + } + AcirValue::Array(values) => { + for value in values { + range_constraint_value(context, value)?; + } + } + AcirValue::DynamicArray(_) => { + unreachable!("Brillig opcodes cannot return dynamic arrays") + } + } + Ok(()) + } + + // This is a hack to ensure that if we're compiling a brillig entrypoint function then + // we don't also add a number of range constraints. + if !unsafe_return_values { + for output_var in &outputs_var { + range_constraint_value(self, output_var)?; + } + } + Ok(outputs_var) + } + fn brillig_array_input( &mut self, var_expressions: &mut Vec, 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 ba4e03bff955..999ff2ddb5d0 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 @@ -167,17 +167,27 @@ impl GeneratedAcir { BlackBoxFuncCall::XOR { lhs: inputs[0][0], rhs: inputs[1][0], output: outputs[0] } } BlackBoxFunc::RANGE => BlackBoxFuncCall::RANGE { input: inputs[0][0] }, - BlackBoxFunc::SHA256 => BlackBoxFuncCall::SHA256 { inputs: inputs[0].clone(), outputs }, - BlackBoxFunc::Blake2s => { - BlackBoxFuncCall::Blake2s { inputs: inputs[0].clone(), outputs } - } - BlackBoxFunc::Blake3 => BlackBoxFuncCall::Blake3 { inputs: inputs[0].clone(), outputs }, + BlackBoxFunc::SHA256 => BlackBoxFuncCall::SHA256 { + inputs: inputs[0].clone(), + outputs: outputs.try_into().expect("Compiler should generate correct size outputs"), + }, + BlackBoxFunc::Blake2s => BlackBoxFuncCall::Blake2s { + inputs: inputs[0].clone(), + outputs: outputs.try_into().expect("Compiler should generate correct size outputs"), + }, + BlackBoxFunc::Blake3 => BlackBoxFuncCall::Blake3 { + inputs: inputs[0].clone(), + outputs: outputs.try_into().expect("Compiler should generate correct size outputs"), + }, BlackBoxFunc::SchnorrVerify => { BlackBoxFuncCall::SchnorrVerify { public_key_x: inputs[0][0], public_key_y: inputs[1][0], // Schnorr signature is an r & s, 32 bytes each - signature: inputs[2].clone(), + signature: inputs[2] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), message: inputs[3].clone(), output: outputs[0], } @@ -195,24 +205,48 @@ impl GeneratedAcir { BlackBoxFunc::EcdsaSecp256k1 => { BlackBoxFuncCall::EcdsaSecp256k1 { // 32 bytes for each public key co-ordinate - public_key_x: inputs[0].clone(), - public_key_y: inputs[1].clone(), + public_key_x: inputs[0] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), + public_key_y: inputs[1] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), // (r,s) are both 32 bytes each, so signature // takes up 64 bytes - signature: inputs[2].clone(), - hashed_message: inputs[3].clone(), + signature: inputs[2] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), + hashed_message: inputs[3] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), output: outputs[0], } } BlackBoxFunc::EcdsaSecp256r1 => { BlackBoxFuncCall::EcdsaSecp256r1 { // 32 bytes for each public key co-ordinate - public_key_x: inputs[0].clone(), - public_key_y: inputs[1].clone(), + public_key_x: inputs[0] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), + public_key_y: inputs[1] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), // (r,s) are both 32 bytes each, so signature // takes up 64 bytes - signature: inputs[2].clone(), - hashed_message: inputs[3].clone(), + signature: inputs[2] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), + hashed_message: inputs[3] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), output: outputs[0], } } @@ -240,11 +274,21 @@ impl GeneratedAcir { } }; - BlackBoxFuncCall::Keccak256 { inputs: inputs[0].clone(), var_message_size, outputs } - } - BlackBoxFunc::Keccakf1600 => { - BlackBoxFuncCall::Keccakf1600 { inputs: inputs[0].clone(), outputs } + BlackBoxFuncCall::Keccak256 { + inputs: inputs[0].clone(), + var_message_size, + outputs: outputs + .try_into() + .expect("Compiler should generate correct size outputs"), + } } + BlackBoxFunc::Keccakf1600 => BlackBoxFuncCall::Keccakf1600 { + inputs: inputs[0] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), + outputs: outputs.try_into().expect("Compiler should generate correct size outputs"), + }, BlackBoxFunc::RecursiveAggregation => BlackBoxFuncCall::RecursiveAggregation { verification_key: inputs[0].clone(), proof: inputs[1].clone(), @@ -286,9 +330,15 @@ impl GeneratedAcir { len: constant_inputs[0].to_u128() as u32, }, BlackBoxFunc::Sha256Compression => BlackBoxFuncCall::Sha256Compression { - inputs: inputs[0].clone(), - hash_values: inputs[1].clone(), - outputs, + inputs: inputs[0] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), + hash_values: inputs[1] + .clone() + .try_into() + .expect("Compiler should generate correct size inputs"), + outputs: outputs.try_into().expect("Compiler should generate correct size outputs"), }, }; @@ -539,6 +589,7 @@ impl GeneratedAcir { Ok(()) } + // TODO: Delete this method once we remove the `Brillig` opcode pub(crate) fn brillig( &mut self, predicate: Option, @@ -567,6 +618,37 @@ impl GeneratedAcir { } } + pub(crate) fn brillig_call( + &mut self, + predicate: Option, + generated_brillig: &GeneratedBrillig, + inputs: Vec, + outputs: Vec, + brillig_function_index: u32, + ) { + let opcode = + AcirOpcode::BrilligCall { id: brillig_function_index, inputs, outputs, predicate }; + self.push_opcode(opcode); + for (brillig_index, call_stack) in generated_brillig.locations.iter() { + self.locations.insert( + OpcodeLocation::Brillig { + acir_index: self.opcodes.len() - 1, + brillig_index: *brillig_index, + }, + call_stack.clone(), + ); + } + for (brillig_index, message) in generated_brillig.assert_messages.iter() { + self.assert_messages.insert( + OpcodeLocation::Brillig { + acir_index: self.opcodes.len() - 1, + brillig_index: *brillig_index, + }, + message.clone(), + ); + } + } + pub(crate) fn last_acir_opcode_location(&self) -> OpcodeLocation { OpcodeLocation::Acir(self.opcodes.len() - 1) } 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 9f2cec5c9490..02b381d79fc9 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 @@ -1,13 +1,14 @@ //! This file holds the pass to convert from Noir's SSA IR to ACIR. mod acir_ir; -use std::collections::HashSet; +use std::collections::{BTreeMap, HashSet}; use std::fmt::Debug; use self::acir_ir::acir_variable::{AcirContext, AcirType, AcirVar}; use super::function_builder::data_bus::DataBus; use super::ir::dfg::CallStack; -use super::ir::instruction::ConstrainError; +use super::ir::function::FunctionId; +use super::ir::instruction::{ConstrainError, UserDefinedConstrainError}; use super::{ ir::{ dfg::DataFlowGraph, @@ -28,6 +29,7 @@ use crate::errors::{InternalError, InternalWarning, RuntimeError, SsaReport}; use crate::ssa::ir::function::InlineType; pub(crate) use acir_ir::generated_acir::GeneratedAcir; +use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::acir::native_types::Witness; use acvm::acir::BlackBoxFunc; use acvm::{ @@ -39,9 +41,54 @@ use im::Vector; use iter_extended::{try_vecmap, vecmap}; use noirc_frontend::Distinctness; +#[derive(Default)] +struct SharedContext { + /// Final list of Brillig functions which will be part of the final program + /// This is shared across `Context` structs as we want one list of Brillig + /// functions across all ACIR artifacts + generated_brillig: Vec, + + /// Maps SSA function index -> Final generated Brillig artifact index. + /// There can be Brillig functions specified in SSA which do not act as + /// entry points in ACIR (e.g. only called by other Brillig functions) + /// This mapping is necessary to use the correct function pointer for a Brillig call. + /// This uses the brillig parameters in the map since using slices with different lengths + /// needs to create different brillig entrypoints + brillig_generated_func_pointers: BTreeMap<(FunctionId, Vec), u32>, +} + +impl SharedContext { + fn generated_brillig_pointer( + &self, + func_id: FunctionId, + arguments: Vec, + ) -> Option<&u32> { + self.brillig_generated_func_pointers.get(&(func_id, arguments)) + } + + fn generated_brillig(&self, func_pointer: usize) -> &GeneratedBrillig { + &self.generated_brillig[func_pointer] + } + + fn insert_generated_brillig( + &mut self, + func_id: FunctionId, + arguments: Vec, + generated_pointer: u32, + code: GeneratedBrillig, + ) { + self.brillig_generated_func_pointers.insert((func_id, arguments), generated_pointer); + self.generated_brillig.push(code); + } + + fn new_generated_pointer(&self) -> u32 { + self.generated_brillig.len() as u32 + } +} + /// Context struct for the acir generation pass. /// May be similar to the Evaluator struct in the current SSA IR. -struct Context { +struct Context<'a> { /// Maps SSA values to `AcirVar`. /// /// This is needed so that we only create a single @@ -91,6 +138,9 @@ struct Context { max_block_id: u32, data_bus: DataBus, + + /// Contains state that is generated and also used across ACIR functions + shared_context: &'a mut SharedContext, } #[derive(Clone)] @@ -181,11 +231,12 @@ impl Ssa { self, brillig: &Brillig, abi_distinctness: Distinctness, - ) -> Result, RuntimeError> { + ) -> Result<(Vec, Vec), RuntimeError> { let mut acirs = Vec::new(); // TODO: can we parallelise this? + let mut shared_context = SharedContext::default(); for function in self.functions.values() { - let context = Context::new(); + let context = Context::new(&mut shared_context); if let Some(mut generated_acir) = context.convert_ssa_function(&self, function, brillig)? { @@ -194,6 +245,10 @@ impl Ssa { } } + let brillig = vecmap(shared_context.generated_brillig, |brillig| BrilligBytecode { + bytecode: brillig.byte_code, + }); + // TODO: check whether doing this for a single circuit's return witnesses is correct. // We probably need it for all foldable circuits, as any circuit being folded is essentially an entry point. However, I do not know how that // plays a part when we potentially want not inlined functions normally as part of the compiler. @@ -215,15 +270,15 @@ impl Ssa { .collect(); main_func_acir.return_witnesses = distinct_return_witness; - Ok(acirs) } - Distinctness::DuplicationAllowed => Ok(acirs), + Distinctness::DuplicationAllowed => {} } + Ok((acirs, brillig)) } } -impl Context { - fn new() -> Context { +impl<'a> Context<'a> { + fn new(shared_context: &'a mut SharedContext) -> Context<'a> { let mut acir_context = AcirContext::default(); let current_side_effects_enabled_var = acir_context.add_constant(FieldElement::one()); @@ -237,6 +292,7 @@ impl Context { internal_mem_block_lengths: HashMap::default(), max_block_id: 0, data_bus: DataBus::default(), + shared_context, } } @@ -307,18 +363,22 @@ impl Context { let outputs: Vec = vecmap(main_func.returns(), |result_id| dfg.type_of_value(*result_id).into()); - let code = self.gen_brillig_for(main_func, arguments, brillig)?; + let code = self.gen_brillig_for(main_func, arguments.clone(), brillig)?; // We specifically do not attempt execution of the brillig code being generated as this can result in it being // replaced with constraints on witnesses to the program outputs. - let output_values = self.acir_context.brillig( + let output_values = self.acir_context.brillig_call( self.current_side_effects_enabled_var, - code, + &code, inputs, outputs, false, true, + // We are guaranteed to have a Brillig function pointer of `0` as main itself is marked as unconstrained + 0, )?; + self.shared_context.insert_generated_brillig(main_func.id(), arguments, 0, code); + let output_vars: Vec<_> = output_values .iter() .flat_map(|value| value.clone().flatten()) @@ -472,8 +532,13 @@ impl Context { let assert_message = if let Some(error) = assert_message { match error.as_ref() { - ConstrainError::Static(string) => Some(string.clone()), - ConstrainError::Dynamic(call_instruction) => { + ConstrainError::Intrinsic(string) + | ConstrainError::UserDefined(UserDefinedConstrainError::Static(string)) => { + Some(string.clone()) + } + ConstrainError::UserDefined(UserDefinedConstrainError::Dynamic( + call_instruction, + )) => { self.convert_ssa_call(call_instruction, dfg, ssa, brillig, &[])?; None } @@ -571,12 +636,12 @@ impl Context { sum + dfg.try_get_array_length(*result_id).unwrap_or(1) }); - let acir_program_id = ssa - .id_to_index + let acir_function_id = ssa + .entry_point_to_generated_index .get(id) .expect("ICE: should have an associated final index"); let output_vars = self.acir_context.call_acir_function( - *acir_program_id, + *acir_function_id, inputs, output_count, self.current_side_effects_enabled_var, @@ -598,24 +663,53 @@ impl Context { ); } } - let inputs = vecmap(arguments, |arg| self.convert_value(*arg, dfg)); let arguments = self.gen_brillig_parameters(arguments, dfg); - let code = self.gen_brillig_for(func, arguments, brillig)?; - let outputs: Vec = vecmap(result_ids, |result_id| { dfg.type_of_value(*result_id).into() }); - let output_values = self.acir_context.brillig( - self.current_side_effects_enabled_var, - code, - inputs, - outputs, - true, - false, - )?; + // Check whether we have already generated Brillig for this function + // If we have, re-use the generated code to set-up the Brillig call. + let output_values = if let Some(generated_pointer) = self + .shared_context + .generated_brillig_pointer(*id, arguments.clone()) + { + let code = self + .shared_context + .generated_brillig(*generated_pointer as usize); + self.acir_context.brillig_call( + self.current_side_effects_enabled_var, + code, + inputs, + outputs, + true, + false, + *generated_pointer, + )? + } else { + let code = + self.gen_brillig_for(func, arguments.clone(), brillig)?; + let generated_pointer = + self.shared_context.new_generated_pointer(); + let output_values = self.acir_context.brillig_call( + self.current_side_effects_enabled_var, + &code, + inputs, + outputs, + true, + false, + generated_pointer, + )?; + self.shared_context.insert_generated_brillig( + *id, + arguments, + generated_pointer, + code, + ); + output_values + }; // Compiler sanity check assert_eq!(result_ids.len(), output_values.len(), "ICE: The number of Brillig output values should match the result ids in SSA"); @@ -2442,19 +2536,27 @@ mod test { }, }; - fn build_basic_foo_with_return(builder: &mut FunctionBuilder, foo_id: FunctionId) { - // acir(fold) fn foo f1 { + fn build_basic_foo_with_return( + builder: &mut FunctionBuilder, + foo_id: FunctionId, + is_brillig_func: bool, + ) { + // fn foo f1 { // b0(v0: Field, v1: Field): // v2 = eq v0, v1 // constrain v2 == u1 0 // return v0 // } - builder.new_function("foo".into(), foo_id, InlineType::Fold); + if is_brillig_func { + builder.new_brillig_function("foo".into(), foo_id); + } else { + builder.new_function("foo".into(), foo_id, InlineType::Fold); + } let foo_v0 = builder.add_parameter(Type::field()); let foo_v1 = builder.add_parameter(Type::field()); let foo_equality_check = builder.insert_binary(foo_v0, BinaryOp::Eq, foo_v1); - let zero = builder.field_constant(0u128); + let zero = builder.numeric_constant(0u128, Type::unsigned(1)); builder.insert_constrain(foo_equality_check, zero, None); builder.terminate_with_return(vec![foo_v0]); } @@ -2488,11 +2590,11 @@ mod test { builder.insert_constrain(main_call1_results[0], main_call2_results[0], None); builder.terminate_with_return(vec![]); - build_basic_foo_with_return(&mut builder, foo_id); + build_basic_foo_with_return(&mut builder, foo_id, false); let ssa = builder.finish(); - let acir_functions = ssa + let (acir_functions, _) = ssa .into_acir(&Brillig::default(), noirc_frontend::Distinctness::Distinct) .expect("Should compile manually written SSA into ACIR"); // Expected result: @@ -2584,11 +2686,11 @@ mod test { builder.insert_constrain(main_call1_results[0], main_call2_results[0], None); builder.terminate_with_return(vec![]); - build_basic_foo_with_return(&mut builder, foo_id); + build_basic_foo_with_return(&mut builder, foo_id, false); let ssa = builder.finish(); - let acir_functions = ssa + let (acir_functions, _) = ssa .into_acir(&Brillig::default(), noirc_frontend::Distinctness::Distinct) .expect("Should compile manually written SSA into ACIR"); // The expected result should look very similar to the abvoe test expect that the input witnesses of the `Call` @@ -2675,11 +2777,11 @@ mod test { .to_vec(); builder.terminate_with_return(vec![foo_call[0]]); - build_basic_foo_with_return(&mut builder, foo_id); + build_basic_foo_with_return(&mut builder, foo_id, false); let ssa = builder.finish(); - let acir_functions = ssa + let (acir_functions, _) = ssa .into_acir(&Brillig::default(), noirc_frontend::Distinctness::Distinct) .expect("Should compile manually written SSA into ACIR"); @@ -2739,4 +2841,82 @@ mod test { _ => panic!("Expected only Call opcode"), } } + + // Test that given multiple calls to the same brillig function we generate only one bytecode + // and the appropriate Brillig call opcodes are generated + #[test] + fn multiple_brillig_calls_one_bytecode() { + // acir(inline) fn main f0 { + // b0(v0: Field, v1: Field): + // v3 = call f1(v0, v1) + // v4 = call f1(v0, v1) + // v5 = call f1(v0, v1) + // v6 = call f1(v0, v1) + // return + // } + // brillig fn foo f1 { + // b0(v0: Field, v1: Field): + // v2 = eq v0, v1 + // constrain v2 == u1 0 + // return v0 + // } + // brillig fn foo f2 { + // b0(v0: Field, v1: Field): + // v2 = eq v0, v1 + // constrain v2 == u1 0 + // return v0 + // } + let foo_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("main".into(), foo_id); + let main_v0 = builder.add_parameter(Type::field()); + let main_v1 = builder.add_parameter(Type::field()); + + let foo_id = Id::test_new(1); + let foo = builder.import_function(foo_id); + let bar_id = Id::test_new(2); + let bar = builder.import_function(bar_id); + + // Insert multiple calls to the same Brillig function + builder.insert_call(foo, vec![main_v0, main_v1], vec![Type::field()]).to_vec(); + builder.insert_call(foo, vec![main_v0, main_v1], vec![Type::field()]).to_vec(); + builder.insert_call(foo, vec![main_v0, main_v1], vec![Type::field()]).to_vec(); + // Interleave a call to a separate Brillig function to make sure that we can call multiple separate Brillig functions + builder.insert_call(bar, vec![main_v0, main_v1], vec![Type::field()]).to_vec(); + builder.insert_call(foo, vec![main_v0, main_v1], vec![Type::field()]).to_vec(); + builder.insert_call(bar, vec![main_v0, main_v1], vec![Type::field()]).to_vec(); + builder.terminate_with_return(vec![]); + + build_basic_foo_with_return(&mut builder, foo_id, true); + build_basic_foo_with_return(&mut builder, bar_id, true); + + let ssa = builder.finish(); + let brillig = ssa.to_brillig(false); + println!("{}", ssa); + + let (acir_functions, brillig_functions) = ssa + .into_acir(&brillig, noirc_frontend::Distinctness::Distinct) + .expect("Should compile manually written SSA into ACIR"); + + assert_eq!(acir_functions.len(), 1, "Should only have a `main` ACIR function"); + assert_eq!( + brillig_functions.len(), + 2, + "Should only have generated a single Brillig function" + ); + + let main_acir = &acir_functions[0]; + let main_opcodes = main_acir.opcodes(); + assert_eq!(main_opcodes.len(), 6, "Should have four calls to f1 and two calls to f2"); + + // We should only have `BrilligCall` opcodes in `main` + for (i, opcode) in main_opcodes.iter().enumerate() { + match opcode { + Opcode::BrilligCall { id, .. } => { + let expected_id = if i == 3 || i == 5 { 1 } else { 0 }; + assert_eq!(*id, expected_id, "Expected an id of {expected_id} but got {id}"); + } + _ => panic!("Expected only Brillig call opcode"), + } + } + } } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 641d971af3c6..04f33d528cd9 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -347,9 +347,11 @@ impl Instruction { let lhs = f(*lhs); let rhs = f(*rhs); let assert_message = assert_message.as_ref().map(|error| match error.as_ref() { - ConstrainError::Dynamic(call_instr) => { + ConstrainError::UserDefined(UserDefinedConstrainError::Dynamic(call_instr)) => { let new_instr = call_instr.map_values(f); - Box::new(ConstrainError::Dynamic(new_instr)) + Box::new(ConstrainError::UserDefined(UserDefinedConstrainError::Dynamic( + new_instr, + ))) } _ => error.clone(), }); @@ -411,7 +413,10 @@ impl Instruction { f(*lhs); f(*rhs); if let Some(error) = assert_error.as_ref() { - if let ConstrainError::Dynamic(call_instr) = error.as_ref() { + if let ConstrainError::UserDefined(UserDefinedConstrainError::Dynamic( + call_instr, + )) = error.as_ref() + { call_instr.for_each_value(f); } } @@ -597,6 +602,14 @@ impl Instruction { #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub(crate) enum ConstrainError { // These are errors which have been hardcoded during SSA gen + Intrinsic(String), + // These are errors issued by the user + UserDefined(UserDefinedConstrainError), +} + +#[derive(Debug, PartialEq, Eq, Hash, Clone)] +pub(crate) enum UserDefinedConstrainError { + // These are errors which come from static strings specified by a Noir program Static(String), // These are errors which come from runtime expressions specified by a Noir program // We store an `Instruction` as we want this Instruction to be atomic in SSA with @@ -606,7 +619,7 @@ pub(crate) enum ConstrainError { impl From for ConstrainError { fn from(value: String) -> Self { - ConstrainError::Static(value) + ConstrainError::Intrinsic(value) } } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/printer.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/printer.rs index fc13ab7307ae..d17d2989341d 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/printer.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/printer.rs @@ -9,7 +9,10 @@ use iter_extended::vecmap; use super::{ basic_block::BasicBlockId, function::Function, - instruction::{ConstrainError, Instruction, InstructionId, TerminatorInstruction}, + instruction::{ + ConstrainError, Instruction, InstructionId, TerminatorInstruction, + UserDefinedConstrainError, + }, value::ValueId, }; @@ -201,10 +204,11 @@ fn display_constrain_error( f: &mut Formatter, ) -> Result { match error { - ConstrainError::Static(assert_message_string) => { + ConstrainError::Intrinsic(assert_message_string) + | ConstrainError::UserDefined(UserDefinedConstrainError::Static(assert_message_string)) => { writeln!(f, "{assert_message_string:?}") } - ConstrainError::Dynamic(assert_message_call) => { + ConstrainError::UserDefined(UserDefinedConstrainError::Dynamic(assert_message_call)) => { display_instruction_inner(function, assert_message_call, f) } } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs index ca6527eb0ecc..aa0368cc2dd2 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs @@ -14,7 +14,7 @@ use crate::ssa::{ ir::{ basic_block::BasicBlockId, function::{Function, FunctionId, Signature}, - instruction::{BinaryOp, ConstrainError, Instruction}, + instruction::{BinaryOp, ConstrainError, Instruction, UserDefinedConstrainError}, types::{NumericType, Type}, value::{Value, ValueId}, }, @@ -93,10 +93,9 @@ impl DefunctionalizationContext { // Constrain instruction potentially hold a call instruction themselves // thus we need to account for them. Instruction::Constrain(_, _, Some(constrain_error)) => { - if let ConstrainError::Dynamic(Instruction::Call { - func: target_func_id, - arguments, - }) = constrain_error.as_ref() + if let ConstrainError::UserDefined(UserDefinedConstrainError::Dynamic( + Instruction::Call { func: target_func_id, arguments }, + )) = constrain_error.as_ref() { (*target_func_id, arguments) } else { @@ -138,9 +137,11 @@ impl DefunctionalizationContext { if let Instruction::Constrain(lhs, rhs, constrain_error_call) = instruction { let new_error_call = if let Some(error) = constrain_error_call { match error.as_ref() { - ConstrainError::Dynamic(_) => { - Some(Box::new(ConstrainError::Dynamic(new_instruction))) - } + ConstrainError::UserDefined( + UserDefinedConstrainError::Dynamic(_), + ) => Some(Box::new(ConstrainError::UserDefined( + UserDefinedConstrainError::Dynamic(new_instruction), + ))), _ => None, } } else { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs index 3fe52f7f0e5e..2a4b5276547b 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs @@ -29,7 +29,9 @@ use super::{ function_builder::data_bus::DataBus, ir::{ function::RuntimeType, - instruction::{BinaryOp, ConstrainError, Instruction, TerminatorInstruction}, + instruction::{ + BinaryOp, ConstrainError, Instruction, TerminatorInstruction, UserDefinedConstrainError, + }, types::Type, value::ValueId, }, @@ -241,6 +243,7 @@ impl<'a> FunctionContext<'a> { Ok(Tree::Branch(vec![string, field_count.into(), fields])) } + ast::Literal::Unit => Ok(Self::unit_value()), } } @@ -707,7 +710,9 @@ impl<'a> FunctionContext<'a> { if let ast::Expression::Literal(ast::Literal::Str(assert_message)) = assert_message_expr.as_ref() { - return Ok(Some(Box::new(ConstrainError::Static(assert_message.to_string())))); + return Ok(Some(Box::new(ConstrainError::UserDefined( + UserDefinedConstrainError::Static(assert_message.to_string()), + )))); } let ast::Expression::Call(call) = assert_message_expr.as_ref() else { @@ -733,7 +738,7 @@ impl<'a> FunctionContext<'a> { } let instr = Instruction::Call { func, arguments }; - Ok(Some(Box::new(ConstrainError::Dynamic(instr)))) + Ok(Some(Box::new(ConstrainError::UserDefined(UserDefinedConstrainError::Dynamic(instr))))) } fn codegen_assign(&mut self, assign: &ast::Assign) -> Result { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs index 9995c031145e..b05a2cbc7414 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs @@ -3,7 +3,7 @@ use std::{collections::BTreeMap, fmt::Display}; use iter_extended::btree_map; use crate::ssa::ir::{ - function::{Function, FunctionId}, + function::{Function, FunctionId, RuntimeType}, map::AtomicCounter, }; @@ -12,7 +12,11 @@ pub(crate) struct Ssa { pub(crate) functions: BTreeMap, pub(crate) main_id: FunctionId, pub(crate) next_id: AtomicCounter, - pub(crate) id_to_index: BTreeMap, + /// Maps SSA entry point function ID -> Final generated ACIR artifact index. + /// There can be functions specified in SSA which do not act as ACIR entry points. + /// This mapping is necessary to use the correct function pointer for an ACIR call, + /// as the final program artifact will be a list of only entry point functions. + pub(crate) entry_point_to_generated_index: BTreeMap, } impl Ssa { @@ -27,9 +31,26 @@ impl Ssa { (f.id(), f) }); - let id_to_index = btree_map(functions.iter().enumerate(), |(i, (id, _))| (*id, i as u32)); + let entry_point_to_generated_index = btree_map( + functions + .iter() + .filter(|(_, func)| { + let runtime = func.runtime(); + match func.runtime() { + RuntimeType::Acir(_) => runtime.is_entry_point() || func.id() == main_id, + RuntimeType::Brillig => false, + } + }) + .enumerate(), + |(i, (id, _))| (*id, i as u32), + ); - Self { functions, main_id, next_id: AtomicCounter::starting_after(max_id), id_to_index } + Self { + functions, + main_id, + next_id: AtomicCounter::starting_after(max_id), + entry_point_to_generated_index, + } } /// Returns the entry-point function of the program diff --git a/noir/noir-repo/compiler/noirc_frontend/Cargo.toml b/noir/noir-repo/compiler/noirc_frontend/Cargo.toml index 03b92e150325..e39ab2fe1062 100644 --- a/noir/noir-repo/compiler/noirc_frontend/Cargo.toml +++ b/noir/noir-repo/compiler/noirc_frontend/Cargo.toml @@ -24,9 +24,16 @@ small-ord-set = "0.1.3" regex = "1.9.1" tracing.workspace = true petgraph = "0.6" +lalrpop-util = { version = "0.20.2", features = ["lexer"] } [dev-dependencies] base64.workspace = true strum = "0.24" strum_macros = "0.24" tempfile.workspace = true + +[build-dependencies] +lalrpop = "0.20.2" + +[features] +experimental_parser = [] diff --git a/noir/noir-repo/compiler/noirc_frontend/build.rs b/noir/noir-repo/compiler/noirc_frontend/build.rs new file mode 100644 index 000000000000..eb896a377aee --- /dev/null +++ b/noir/noir-repo/compiler/noirc_frontend/build.rs @@ -0,0 +1,28 @@ +use std::fs::{read_to_string, File}; +use std::io::Write; + +fn main() { + lalrpop::Configuration::new() + .emit_rerun_directives(true) + .use_cargo_dir_conventions() + .process() + .unwrap(); + + // here, we get a lint error from "extern crate core" so patching that until lalrpop does + // (adding cfg directives appears to be unsupported by lalrpop) + let out_dir = std::env::var("OUT_DIR").unwrap(); + let parser_path = std::path::Path::new(&out_dir).join("noir_parser.rs"); + let content_str = read_to_string(parser_path.clone()).unwrap(); + let mut parser_file = File::create(parser_path).unwrap(); + for line in content_str.lines() { + if line.contains("extern crate core") { + parser_file + .write_all( + format!("{}\n", line.replace("extern crate core", "use core")).as_bytes(), + ) + .unwrap(); + } else { + parser_file.write_all(format!("{}\n", line).as_bytes()).unwrap(); + } + } +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/ast/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/ast/mod.rs index 4547dc2a176e..254ec4a75908 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/ast/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/ast/mod.rs @@ -112,6 +112,9 @@ pub enum UnresolvedTypeData { /*env:*/ Box, ), + // The type of quoted code for metaprogramming + Code, + Unspecified, // This is for when the user declares a variable without specifying it's type Error, } @@ -200,6 +203,7 @@ impl std::fmt::Display for UnresolvedTypeData { } } MutableReference(element) => write!(f, "&mut {element}"), + Code => write!(f, "Code"), Unit => write!(f, "()"), Error => write!(f, "error"), Unspecified => write!(f, "unspecified"), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs new file mode 100644 index 000000000000..8ffcbce7d62f --- /dev/null +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs @@ -0,0 +1,350 @@ +use iter_extended::vecmap; +use noirc_errors::{Span, Spanned}; + +use crate::ast::{ConstrainStatement, Expression, Statement, StatementKind}; +use crate::hir_def::expr::{HirArrayLiteral, HirExpression, HirIdent}; +use crate::hir_def::stmt::{HirLValue, HirPattern, HirStatement}; +use crate::macros_api::HirLiteral; +use crate::node_interner::{ExprId, NodeInterner, StmtId}; +use crate::{ + ArrayLiteral, AssignStatement, BlockExpression, CallExpression, CastExpression, ConstrainKind, + ConstructorExpression, ExpressionKind, ForLoopStatement, ForRange, Ident, IfExpression, + IndexExpression, InfixExpression, LValue, Lambda, LetStatement, Literal, + MemberAccessExpression, MethodCallExpression, Path, Pattern, PrefixExpression, Type, + UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression, +}; + +// TODO: +// - Full path for idents & types +// - Assert/AssertEq information lost +// - The type name span is lost in constructor patterns & expressions +// - All type spans are lost +// - Type::TypeVariable has no equivalent in the Ast + +impl StmtId { + #[allow(unused)] + fn to_ast(self, interner: &NodeInterner) -> Statement { + let statement = interner.statement(&self); + let span = interner.statement_span(&self); + + let kind = match statement { + HirStatement::Let(let_stmt) => { + let pattern = let_stmt.pattern.into_ast(interner); + let r#type = interner.id_type(let_stmt.expression).to_ast(); + let expression = let_stmt.expression.to_ast(interner); + StatementKind::Let(LetStatement { + pattern, + r#type, + expression, + attributes: Vec::new(), + }) + } + HirStatement::Constrain(constrain) => { + let expr = constrain.0.to_ast(interner); + let message = constrain.2.map(|message| message.to_ast(interner)); + + // TODO: Find difference in usage between Assert & AssertEq + StatementKind::Constrain(ConstrainStatement(expr, message, ConstrainKind::Assert)) + } + HirStatement::Assign(assign) => StatementKind::Assign(AssignStatement { + lvalue: assign.lvalue.into_ast(interner), + expression: assign.expression.to_ast(interner), + }), + HirStatement::For(for_stmt) => StatementKind::For(ForLoopStatement { + identifier: for_stmt.identifier.to_ast(interner), + range: ForRange::Range( + for_stmt.start_range.to_ast(interner), + for_stmt.end_range.to_ast(interner), + ), + block: for_stmt.block.to_ast(interner), + span, + }), + HirStatement::Break => StatementKind::Break, + HirStatement::Continue => StatementKind::Continue, + HirStatement::Expression(expr) => StatementKind::Expression(expr.to_ast(interner)), + HirStatement::Semi(expr) => StatementKind::Semi(expr.to_ast(interner)), + HirStatement::Error => StatementKind::Error, + }; + + Statement { kind, span } + } +} + +impl ExprId { + #[allow(unused)] + fn to_ast(self, interner: &NodeInterner) -> Expression { + let expression = interner.expression(&self); + let span = interner.expr_span(&self); + + let kind = match expression { + HirExpression::Ident(ident) => { + let path = Path::from_ident(ident.to_ast(interner)); + ExpressionKind::Variable(path) + } + HirExpression::Literal(HirLiteral::Array(array)) => { + let array = array.into_ast(interner, span); + ExpressionKind::Literal(Literal::Array(array)) + } + HirExpression::Literal(HirLiteral::Slice(array)) => { + let array = array.into_ast(interner, span); + ExpressionKind::Literal(Literal::Slice(array)) + } + HirExpression::Literal(HirLiteral::Bool(value)) => { + ExpressionKind::Literal(Literal::Bool(value)) + } + HirExpression::Literal(HirLiteral::Integer(value, sign)) => { + ExpressionKind::Literal(Literal::Integer(value, sign)) + } + HirExpression::Literal(HirLiteral::Str(string)) => { + ExpressionKind::Literal(Literal::Str(string)) + } + HirExpression::Literal(HirLiteral::FmtStr(string, _exprs)) => { + // TODO: Is throwing away the exprs here valid? + ExpressionKind::Literal(Literal::FmtStr(string)) + } + HirExpression::Literal(HirLiteral::Unit) => ExpressionKind::Literal(Literal::Unit), + HirExpression::Block(expr) => { + let statements = vecmap(expr.statements, |statement| statement.to_ast(interner)); + ExpressionKind::Block(BlockExpression { statements }) + } + HirExpression::Prefix(prefix) => ExpressionKind::Prefix(Box::new(PrefixExpression { + operator: prefix.operator, + rhs: prefix.rhs.to_ast(interner), + })), + HirExpression::Infix(infix) => ExpressionKind::Infix(Box::new(InfixExpression { + lhs: infix.lhs.to_ast(interner), + operator: Spanned::from(infix.operator.location.span, infix.operator.kind), + rhs: infix.rhs.to_ast(interner), + })), + HirExpression::Index(index) => ExpressionKind::Index(Box::new(IndexExpression { + collection: index.collection.to_ast(interner), + index: index.index.to_ast(interner), + })), + HirExpression::Constructor(constructor) => { + let type_name = constructor.r#type.borrow().name.to_string(); + let type_name = Path::from_single(type_name, span); + let fields = + vecmap(constructor.fields, |(name, expr)| (name, expr.to_ast(interner))); + + ExpressionKind::Constructor(Box::new(ConstructorExpression { type_name, fields })) + } + HirExpression::MemberAccess(access) => { + ExpressionKind::MemberAccess(Box::new(MemberAccessExpression { + lhs: access.lhs.to_ast(interner), + rhs: access.rhs, + })) + } + HirExpression::Call(call) => { + let func = Box::new(call.func.to_ast(interner)); + let arguments = vecmap(call.arguments, |arg| arg.to_ast(interner)); + ExpressionKind::Call(Box::new(CallExpression { func, arguments })) + } + HirExpression::MethodCall(method_call) => { + ExpressionKind::MethodCall(Box::new(MethodCallExpression { + object: method_call.object.to_ast(interner), + method_name: method_call.method, + arguments: vecmap(method_call.arguments, |arg| arg.to_ast(interner)), + })) + } + HirExpression::Cast(cast) => { + let lhs = cast.lhs.to_ast(interner); + let r#type = cast.r#type.to_ast(); + ExpressionKind::Cast(Box::new(CastExpression { lhs, r#type })) + } + HirExpression::If(if_expr) => ExpressionKind::If(Box::new(IfExpression { + condition: if_expr.condition.to_ast(interner), + consequence: if_expr.consequence.to_ast(interner), + alternative: if_expr.alternative.map(|expr| expr.to_ast(interner)), + })), + HirExpression::Tuple(fields) => { + ExpressionKind::Tuple(vecmap(fields, |field| field.to_ast(interner))) + } + HirExpression::Lambda(lambda) => { + let parameters = vecmap(lambda.parameters, |(pattern, typ)| { + (pattern.into_ast(interner), typ.to_ast()) + }); + let return_type = lambda.return_type.to_ast(); + let body = lambda.body.to_ast(interner); + ExpressionKind::Lambda(Box::new(Lambda { parameters, return_type, body })) + } + HirExpression::Quote(block) => ExpressionKind::Quote(block), + HirExpression::Error => ExpressionKind::Error, + }; + + Expression::new(kind, span) + } +} + +impl HirPattern { + fn into_ast(self, interner: &NodeInterner) -> Pattern { + match self { + HirPattern::Identifier(ident) => Pattern::Identifier(ident.to_ast(interner)), + HirPattern::Mutable(pattern, location) => { + let pattern = Box::new(pattern.into_ast(interner)); + Pattern::Mutable(pattern, location.span, false) + } + HirPattern::Tuple(patterns, location) => { + let patterns = vecmap(patterns, |pattern| pattern.into_ast(interner)); + Pattern::Tuple(patterns, location.span) + } + HirPattern::Struct(typ, patterns, location) => { + let patterns = + vecmap(patterns, |(name, pattern)| (name, pattern.into_ast(interner))); + let name = match typ.follow_bindings() { + Type::Struct(struct_def, _) => { + let struct_def = struct_def.borrow(); + struct_def.name.0.contents.clone() + } + // This pass shouldn't error so if the type isn't a struct we just get a string + // representation of any other type and use that. We're relying on name + // resolution to fail later when this Ast is re-converted to Hir. + other => other.to_string(), + }; + // The name span is lost here + let path = Path::from_single(name, location.span); + Pattern::Struct(path, patterns, location.span) + } + } + } +} + +impl HirIdent { + fn to_ast(&self, interner: &NodeInterner) -> Ident { + let name = interner.definition_name(self.id).to_owned(); + Ident(Spanned::from(self.location.span, name)) + } +} + +impl Type { + fn to_ast(&self) -> UnresolvedType { + let typ = match self { + Type::FieldElement => UnresolvedTypeData::FieldElement, + Type::Array(length, element) => { + let length = length.to_type_expression(); + let element = Box::new(element.to_ast()); + UnresolvedTypeData::Array(length, element) + } + Type::Slice(element) => { + let element = Box::new(element.to_ast()); + UnresolvedTypeData::Slice(element) + } + Type::Integer(sign, bit_size) => UnresolvedTypeData::Integer(*sign, *bit_size), + Type::Bool => UnresolvedTypeData::Bool, + Type::String(length) => { + let length = length.to_type_expression(); + UnresolvedTypeData::String(Some(length)) + } + Type::FmtString(length, element) => { + let length = length.to_type_expression(); + let element = Box::new(element.to_ast()); + UnresolvedTypeData::FormatString(length, element) + } + Type::Unit => UnresolvedTypeData::Unit, + Type::Tuple(fields) => { + let fields = vecmap(fields, |field| field.to_ast()); + UnresolvedTypeData::Tuple(fields) + } + Type::Struct(def, generics) => { + let struct_def = def.borrow(); + let generics = vecmap(generics, |generic| generic.to_ast()); + let name = Path::from_ident(struct_def.name.clone()); + UnresolvedTypeData::Named(name, generics, false) + } + Type::Alias(type_def, generics) => { + // Keep the alias name instead of expanding this in case the + // alias' definition was changed + let type_def = type_def.borrow(); + let generics = vecmap(generics, |generic| generic.to_ast()); + let name = Path::from_ident(type_def.name.clone()); + UnresolvedTypeData::Named(name, generics, false) + } + Type::TypeVariable(_, _) => todo!("Convert Type::TypeVariable Hir -> Ast"), + Type::TraitAsType(_, name, generics) => { + let generics = vecmap(generics, |generic| generic.to_ast()); + let name = Path::from_single(name.as_ref().clone(), Span::default()); + UnresolvedTypeData::TraitAsType(name, generics) + } + Type::NamedGeneric(_, name) => { + let name = Path::from_single(name.as_ref().clone(), Span::default()); + UnresolvedTypeData::TraitAsType(name, Vec::new()) + } + Type::Function(args, ret, env) => { + let args = vecmap(args, |arg| arg.to_ast()); + let ret = Box::new(ret.to_ast()); + let env = Box::new(env.to_ast()); + UnresolvedTypeData::Function(args, ret, env) + } + Type::MutableReference(element) => { + let element = Box::new(element.to_ast()); + UnresolvedTypeData::MutableReference(element) + } + // Type::Forall is only for generic functions which don't store a type + // in their Ast so they don't need to call to_ast for their Forall type. + // Since there is no UnresolvedTypeData equivalent for Type::Forall, we use + // this to ignore this case since it shouldn't be needed anyway. + Type::Forall(_, typ) => return typ.to_ast(), + Type::Constant(_) => panic!("Type::Constant where a type was expected: {self:?}"), + Type::Code => UnresolvedTypeData::Code, + Type::Error => UnresolvedTypeData::Error, + }; + + UnresolvedType { typ, span: None } + } + + fn to_type_expression(&self) -> UnresolvedTypeExpression { + let span = Span::default(); + + match self.follow_bindings() { + Type::Constant(length) => UnresolvedTypeExpression::Constant(length, span), + Type::NamedGeneric(_, name) => { + let path = Path::from_single(name.as_ref().clone(), span); + UnresolvedTypeExpression::Variable(path) + } + // TODO: This should be turned into a proper error. + other => panic!("Cannot represent {other:?} as type expression"), + } + } +} + +impl HirLValue { + fn into_ast(self, interner: &NodeInterner) -> LValue { + match self { + HirLValue::Ident(ident, _) => LValue::Ident(ident.to_ast(interner)), + HirLValue::MemberAccess { object, field_name, field_index: _, typ: _, location } => { + let object = Box::new(object.into_ast(interner)); + LValue::MemberAccess { object, field_name, span: location.span } + } + HirLValue::Index { array, index, typ: _, location } => { + let array = Box::new(array.into_ast(interner)); + let index = index.to_ast(interner); + LValue::Index { array, index, span: location.span } + } + HirLValue::Dereference { lvalue, element_type: _, location } => { + let lvalue = Box::new(lvalue.into_ast(interner)); + LValue::Dereference(lvalue, location.span) + } + } + } +} + +impl HirArrayLiteral { + fn into_ast(self, interner: &NodeInterner, span: Span) -> ArrayLiteral { + match self { + HirArrayLiteral::Standard(elements) => { + ArrayLiteral::Standard(vecmap(elements, |element| element.to_ast(interner))) + } + HirArrayLiteral::Repeated { repeated_element, length } => { + let repeated_element = Box::new(repeated_element.to_ast(interner)); + let length = match length { + Type::Constant(length) => { + let literal = Literal::Integer((length as u128).into(), false); + let kind = ExpressionKind::Literal(literal); + Box::new(Expression::new(kind, span)) + } + other => panic!("Cannot convert non-constant type for repeated array literal from Hir -> Ast: {other:?}"), + }; + ArrayLiteral::Repeated { repeated_element, length } + } + } + } +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/mod.rs new file mode 100644 index 000000000000..91621c857cff --- /dev/null +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/mod.rs @@ -0,0 +1 @@ +mod hir_to_ast; diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/mod.rs index 727a6596df1a..55dc22d6c5d0 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/mod.rs @@ -1,3 +1,4 @@ +pub mod comptime; pub mod def_collector; pub mod def_map; pub mod resolution; @@ -157,7 +158,8 @@ impl Context<'_, '_> { } } - /// Recursively walks down the crate dependency graph from crate_id until we reach requested crate + /// Tries to find the requested crate in the current one's dependencies, + /// otherwise walks down the crate dependency graph from crate_id until we reach it. /// This is needed in case a library (lib1) re-export a structure defined in another library (lib2) /// In that case, we will get [lib1,lib2] when looking for a struct defined in lib2, /// re-exported by lib1 and used by the main crate. @@ -167,16 +169,26 @@ impl Context<'_, '_> { crate_id: &CrateId, target_crate_id: &CrateId, ) -> Option> { - for dep in &self.crate_graph[crate_id].dependencies { - if &dep.crate_id == target_crate_id { - return Some(vec![dep.name.to_string()]); - } - if let Some(mut path) = self.find_dependencies(&dep.crate_id, target_crate_id) { - path.insert(0, dep.name.to_string()); - return Some(path); - } - } - None + self.crate_graph[crate_id] + .dependencies + .iter() + .find_map(|dep| { + if &dep.crate_id == target_crate_id { + Some(vec![dep.name.to_string()]) + } else { + None + } + }) + .or_else(|| { + self.crate_graph[crate_id].dependencies.iter().find_map(|dep| { + if let Some(mut path) = self.find_dependencies(&dep.crate_id, target_crate_id) { + path.insert(0, dep.name.to_string()); + Some(path) + } else { + None + } + }) + }) } pub fn function_meta(&self, func_id: &FuncId) -> &FuncMeta { @@ -241,7 +253,7 @@ impl Context<'_, '_> { .get_all_contracts(&self.def_interner) } - fn module(&self, module_id: def_map::ModuleId) -> &def_map::ModuleData { + pub fn module(&self, module_id: def_map::ModuleId) -> &def_map::ModuleData { module_id.module(&self.def_maps) } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 08b12069d768..9180201fe17e 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -502,6 +502,7 @@ impl<'a> Resolver<'a> { let fields = self.resolve_type_inner(*fields, new_variables); Type::FmtString(Box::new(resolved_size), Box::new(fields)) } + Code => Type::Code, Unit => Type::Unit, Unspecified => Type::Error, Error => Type::Error, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs b/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs index 265b9e4b5a3c..2d1ebf530e3f 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs @@ -2,7 +2,9 @@ use crate::token::{Attribute, DocStyle}; use super::{ errors::LexerErrorKind, - token::{IntType, Keyword, SpannedToken, Token, Tokens}, + token::{ + token_to_borrowed_token, BorrowedToken, IntType, Keyword, SpannedToken, Token, Tokens, + }, }; use acvm::FieldElement; use noirc_errors::{Position, Span}; @@ -21,6 +23,21 @@ pub struct Lexer<'a> { pub type SpannedTokenResult = Result; +pub(crate) fn from_spanned_token_result( + token_result: &SpannedTokenResult, +) -> Result<(usize, BorrowedToken<'_>, usize), LexerErrorKind> { + token_result + .as_ref() + .map(|spanned_token| { + ( + spanned_token.to_span().start() as usize, + token_to_borrowed_token(spanned_token.into()), + spanned_token.to_span().end() as usize, + ) + }) + .map_err(Clone::clone) +} + impl<'a> Lexer<'a> { /// Given a source file of noir code, return all the tokens in the file /// in order, along with any lexing errors that occurred. @@ -94,7 +111,7 @@ impl<'a> Lexer<'a> { fn next_token(&mut self) -> SpannedTokenResult { match self.next_char() { - Some(x) if x.is_whitespace() => { + Some(x) if Self::is_code_whitespace(x) => { let spanned = self.eat_whitespace(x); if self.skip_whitespaces { self.next_token() @@ -560,16 +577,21 @@ impl<'a> Lexer<'a> { } } + fn is_code_whitespace(c: char) -> bool { + c == '\t' || c == '\n' || c == '\r' || c == ' ' + } + /// Skips white space. They are not significant in the source language fn eat_whitespace(&mut self, initial_char: char) -> SpannedToken { let start = self.position; - let whitespace = self.eat_while(initial_char.into(), |ch| ch.is_whitespace()); + let whitespace = self.eat_while(initial_char.into(), Self::is_code_whitespace); SpannedToken::new(Token::Whitespace(whitespace), Span::inclusive(start, self.position)) } } impl<'a> Iterator for Lexer<'a> { type Item = SpannedTokenResult; + fn next(&mut self) -> Option { if self.done { None @@ -578,10 +600,12 @@ impl<'a> Iterator for Lexer<'a> { } } } + #[cfg(test)] mod tests { use super::*; use crate::token::{FunctionAttribute, SecondaryAttribute, TestScope}; + #[test] fn test_single_double_char() { let input = "! != + ( ) { } [ ] | , ; : :: < <= > >= & - -> . .. % / * = == << >>"; diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs index 357b1ead593e..86f26fd1c973 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs @@ -9,12 +9,105 @@ use crate::lexer::errors::LexerErrorKind; /// smallest unit of grammar. A parser may (will) decide to parse /// items differently depending on the Tokens present but will /// never parse the same ordering of identical tokens differently. +#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] +pub enum BorrowedToken<'input> { + Ident(&'input str), + Int(FieldElement), + Bool(bool), + Str(&'input str), + /// the u8 is the number of hashes, i.e. r###.. + RawStr(&'input str, u8), + FmtStr(&'input str), + Keyword(Keyword), + IntType(IntType), + Attribute(Attribute), + LineComment(&'input str, Option), + BlockComment(&'input str, Option), + /// < + Less, + /// <= + LessEqual, + /// > + Greater, + /// >= + GreaterEqual, + /// == + Equal, + /// != + NotEqual, + /// + + Plus, + /// - + Minus, + /// * + Star, + /// / + Slash, + /// % + Percent, + /// & + Ampersand, + /// ^ + Caret, + /// << + ShiftLeft, + /// >> + ShiftRight, + /// . + Dot, + /// .. + DoubleDot, + /// ( + LeftParen, + /// ) + RightParen, + /// { + LeftBrace, + /// } + RightBrace, + /// [ + LeftBracket, + /// ] + RightBracket, + /// -> + Arrow, + /// | + Pipe, + /// # + Pound, + /// , + Comma, + /// : + Colon, + /// :: + DoubleColon, + /// ; + Semicolon, + /// ! + Bang, + /// = + Assign, + #[allow(clippy::upper_case_acronyms)] + EOF, + + Whitespace(&'input str), + + /// An invalid character is one that is not in noir's language or grammar. + /// + /// We don't report invalid tokens in the source as errors until parsing to + /// avoid reporting the error twice (once while lexing, again when it is encountered + /// during parsing). Reporting during lexing then removing these from the token stream + /// would not be equivalent as it would change the resulting parse. + Invalid(char), +} + #[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] pub enum Token { Ident(String), Int(FieldElement), Bool(bool), Str(String), + /// the u8 is the number of hashes, i.e. r###.. RawStr(String, u8), FmtStr(String), Keyword(Keyword), @@ -100,6 +193,57 @@ pub enum Token { Invalid(char), } +pub fn token_to_borrowed_token(token: &Token) -> BorrowedToken<'_> { + match token { + Token::Ident(ref s) => BorrowedToken::Ident(s), + Token::Int(n) => BorrowedToken::Int(*n), + Token::Bool(b) => BorrowedToken::Bool(*b), + Token::Str(ref b) => BorrowedToken::Str(b), + Token::FmtStr(ref b) => BorrowedToken::FmtStr(b), + Token::RawStr(ref b, hashes) => BorrowedToken::RawStr(b, *hashes), + Token::Keyword(k) => BorrowedToken::Keyword(*k), + Token::Attribute(ref a) => BorrowedToken::Attribute(a.clone()), + Token::LineComment(ref s, _style) => BorrowedToken::LineComment(s, *_style), + Token::BlockComment(ref s, _style) => BorrowedToken::BlockComment(s, *_style), + Token::IntType(ref i) => BorrowedToken::IntType(i.clone()), + Token::Less => BorrowedToken::Less, + Token::LessEqual => BorrowedToken::LessEqual, + Token::Greater => BorrowedToken::Greater, + Token::GreaterEqual => BorrowedToken::GreaterEqual, + Token::Equal => BorrowedToken::Equal, + Token::NotEqual => BorrowedToken::NotEqual, + Token::Plus => BorrowedToken::Plus, + Token::Minus => BorrowedToken::Minus, + Token::Star => BorrowedToken::Star, + Token::Slash => BorrowedToken::Slash, + Token::Percent => BorrowedToken::Percent, + Token::Ampersand => BorrowedToken::Ampersand, + Token::Caret => BorrowedToken::Caret, + Token::ShiftLeft => BorrowedToken::ShiftLeft, + Token::ShiftRight => BorrowedToken::ShiftRight, + Token::Dot => BorrowedToken::Dot, + Token::DoubleDot => BorrowedToken::DoubleDot, + Token::LeftParen => BorrowedToken::LeftParen, + Token::RightParen => BorrowedToken::RightParen, + Token::LeftBrace => BorrowedToken::LeftBrace, + Token::RightBrace => BorrowedToken::RightBrace, + Token::LeftBracket => BorrowedToken::LeftBracket, + Token::RightBracket => BorrowedToken::RightBracket, + Token::Arrow => BorrowedToken::Arrow, + Token::Pipe => BorrowedToken::Pipe, + Token::Pound => BorrowedToken::Pound, + Token::Comma => BorrowedToken::Comma, + Token::Colon => BorrowedToken::Colon, + Token::DoubleColon => BorrowedToken::DoubleColon, + Token::Semicolon => BorrowedToken::Semicolon, + Token::Assign => BorrowedToken::Assign, + Token::Bang => BorrowedToken::Bang, + Token::EOF => BorrowedToken::EOF, + Token::Invalid(c) => BorrowedToken::Invalid(*c), + Token::Whitespace(ref s) => BorrowedToken::Whitespace(s), + } +} + #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] pub enum DocStyle { Outer, @@ -126,6 +270,12 @@ impl From for Token { } } +impl<'a> From<&'a SpannedToken> for &'a Token { + fn from(spt: &'a SpannedToken) -> Self { + &spt.0.contents + } +} + impl SpannedToken { pub fn new(token: Token, span: Span) -> SpannedToken { SpannedToken(Spanned::from(span, token)) diff --git a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/ast.rs b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/ast.rs index 7d20c2bcfee3..d9c33d8604e2 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/ast.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/ast.rs @@ -92,6 +92,7 @@ pub enum Literal { Slice(ArrayLiteral), Integer(FieldElement, Type, Location), Bool(bool), + Unit, Str(String), FmtStr(String, u64, Box), } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs index 6aa0abce152c..4e779244d309 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -52,14 +52,13 @@ struct LambdaContext { /// This struct holds the FIFO queue of functions to monomorphize, which is added to /// whenever a new (function, type) combination is encountered. struct Monomorphizer<'interner> { - /// Globals are keyed by their unique ID and expected type so that we can monomorphize - /// a new version of the global for each type. Note that 'global' here means 'globally - /// visible' and thus includes both functions and global variables. + /// Functions are keyed by their unique ID and expected type so that we can monomorphize + /// a new version of the function for each type. /// /// Using nested HashMaps here lets us avoid cloning HirTypes when calling .get() - globals: HashMap>, + functions: HashMap>, - /// Unlike globals, locals are only keyed by their unique ID because they are never + /// Unlike functions, locals are only keyed by their unique ID because they are never /// duplicated during monomorphization. Doing so would allow them to be used polymorphically /// but would also cause them to be re-evaluated which is a performance trap that would /// confuse users. @@ -165,7 +164,7 @@ pub fn monomorphize_debug( impl<'interner> Monomorphizer<'interner> { fn new(interner: &'interner mut NodeInterner, debug_type_tracker: DebugTypeTracker) -> Self { Monomorphizer { - globals: HashMap::new(), + functions: HashMap::new(), locals: HashMap::new(), queue: VecDeque::new(), finished_functions: BTreeMap::new(), @@ -203,7 +202,7 @@ impl<'interner> Monomorphizer<'interner> { trait_method: Option, ) -> Definition { let typ = typ.follow_bindings(); - match self.globals.get(&id).and_then(|inner_map| inner_map.get(&typ)) { + match self.functions.get(&id).and_then(|inner_map| inner_map.get(&typ)) { Some(id) => Definition::Function(*id), None => { // Function has not been monomorphized yet @@ -251,8 +250,8 @@ impl<'interner> Monomorphizer<'interner> { } /// Prerequisite: typ = typ.follow_bindings() - fn define_global(&mut self, id: node_interner::FuncId, typ: HirType, new_id: FuncId) { - self.globals.entry(id).or_default().insert(typ, new_id); + fn define_function(&mut self, id: node_interner::FuncId, typ: HirType, new_id: FuncId) { + self.functions.entry(id).or_default().insert(typ, new_id); } fn compile_main( @@ -786,7 +785,7 @@ impl<'interner> Monomorphizer<'interner> { }) } - /// A local (ie non-global) ident only + /// A local (ie non-function) ident only fn local_ident( &mut self, ident: &HirIdent, @@ -1280,7 +1279,7 @@ impl<'interner> Monomorphizer<'interner> { trait_method: Option, ) -> FuncId { let new_id = self.next_function_id(); - self.define_global(id, function_type.clone(), new_id); + self.define_function(id, function_type.clone(), new_id); let bindings = self.interner.get_instantiation_bindings(expr_id); let bindings = self.follow_bindings(bindings); @@ -1553,9 +1552,7 @@ impl<'interner> Monomorphizer<'interner> { ast::Expression::Literal(ast::Literal::Integer(0_u128.into(), typ, location)) } ast::Type::Bool => ast::Expression::Literal(ast::Literal::Bool(false)), - // There is no unit literal currently. Replace it with 'false' since it should be ignored - // anyway. - ast::Type::Unit => ast::Expression::Literal(ast::Literal::Bool(false)), + ast::Type::Unit => ast::Expression::Literal(ast::Literal::Unit), ast::Type::Array(length, element_type) => { let element = self.zeroed_value_of_type(element_type.as_ref(), location); ast::Expression::Literal(ast::Literal::Array(ast::ArrayLiteral { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/printer.rs b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/printer.rs index c253bfe7930e..ea8f079cc2f0 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/printer.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/printer.rs @@ -110,6 +110,9 @@ impl AstPrinter { s.fmt(f)?; write!(f, "\"") } + super::ast::Literal::Unit => { + write!(f, "()") + } } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs b/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs index ffd760d6d7f1..153c7e45d4a2 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs @@ -223,10 +223,10 @@ pub enum TraitImplKind { /// /// Additionally, types can define specialized impls with methods of the same name /// as long as these specialized impls do not overlap. E.g. `impl Struct` and `impl Struct` -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub struct Methods { - direct: Vec, - trait_impl_methods: Vec, + pub direct: Vec, + pub trait_impl_methods: Vec, } /// All the information from a function that is filled out during definition collection rather than @@ -917,10 +917,32 @@ impl NodeInterner { self.id_location(expr_id) } + pub fn statement_span(&self, stmt_id: &StmtId) -> Span { + self.id_location(stmt_id).span + } + pub fn get_struct(&self, id: StructId) -> Shared { self.structs[&id].clone() } + pub fn get_struct_methods(&self, id: StructId) -> Vec { + self.struct_methods + .keys() + .filter_map(|(key_id, name)| { + if key_id == &id { + Some( + self.struct_methods + .get(&(*key_id, name.clone())) + .expect("get_struct_methods given invalid StructId") + .clone(), + ) + } else { + None + } + }) + .collect() + } + pub fn get_trait(&self, id: TraitId) -> &Trait { &self.traits[&id] } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/noir_parser.lalrpop b/noir/noir-repo/compiler/noirc_frontend/src/noir_parser.lalrpop new file mode 100644 index 000000000000..c8d293fb72f6 --- /dev/null +++ b/noir/noir-repo/compiler/noirc_frontend/src/noir_parser.lalrpop @@ -0,0 +1,164 @@ +use noirc_errors::Span; + +use crate::lexer::token::BorrowedToken; +use crate::lexer::token as noir_token; +use crate::lexer::errors::LexerErrorKind; +use crate::parser::TopLevelStatement; +use crate::{Ident, Path, PathKind, UseTree, UseTreeKind}; + +use lalrpop_util::ErrorRecovery; + +grammar<'input, 'err>(input: &'input str, errors: &'err mut [ErrorRecovery, &'static str>]); + +extern { + type Location = usize; + + type Error = LexerErrorKind; + + // NOTE: each token needs a terminal defined + enum BorrowedToken<'input> { + string => BorrowedToken::Str(<&'input str>), + ident => BorrowedToken::Ident(<&'input str>), + + // symbols + "<" => BorrowedToken::Less, + "<=" => BorrowedToken::LessEqual, + ">" => BorrowedToken::Greater, + ">=" => BorrowedToken::GreaterEqual, + "==" => BorrowedToken::Equal, + "!=" => BorrowedToken::NotEqual, + "+" => BorrowedToken::Plus, + "-" => BorrowedToken::Minus, + "*" => BorrowedToken::Star, + "/" => BorrowedToken::Slash, + "%" => BorrowedToken::Percent, + "&" => BorrowedToken::Ampersand, + "^" => BorrowedToken::Caret, + "<<" => BorrowedToken::ShiftLeft, + ">>" => BorrowedToken::ShiftRight, + "." => BorrowedToken::Dot, + ".." => BorrowedToken::DoubleDot, + "(" => BorrowedToken::LeftParen, + ")" => BorrowedToken::RightParen, + "{" => BorrowedToken::LeftBrace, + "}" => BorrowedToken::RightBrace, + "[" => BorrowedToken::LeftBracket, + "]" => BorrowedToken::RightBracket, + "->" => BorrowedToken::Arrow, + "|" => BorrowedToken::Pipe, + "#" => BorrowedToken::Pound, + "," => BorrowedToken::Comma, + ":" => BorrowedToken::Colon, + "::" => BorrowedToken::DoubleColon, + ";" => BorrowedToken::Semicolon, + "!" => BorrowedToken::Bang, + "=" => BorrowedToken::Assign, + // keywords + "as" => BorrowedToken::Keyword(noir_token::Keyword::As), + "assert" => BorrowedToken::Keyword(noir_token::Keyword::Assert), + "assert_eq" => BorrowedToken::Keyword(noir_token::Keyword::AssertEq), + "bool" => BorrowedToken::Keyword(noir_token::Keyword::Bool), + "break" => BorrowedToken::Keyword(noir_token::Keyword::Break), + "call_data" => BorrowedToken::Keyword(noir_token::Keyword::CallData), + "char" => BorrowedToken::Keyword(noir_token::Keyword::Char), + "comptime" => BorrowedToken::Keyword(noir_token::Keyword::CompTime), + "constrain" => BorrowedToken::Keyword(noir_token::Keyword::Constrain), + "continue" => BorrowedToken::Keyword(noir_token::Keyword::Continue), + "contract" => BorrowedToken::Keyword(noir_token::Keyword::Contract), + "crate" => BorrowedToken::Keyword(noir_token::Keyword::Crate), + "dep" => BorrowedToken::Keyword(noir_token::Keyword::Dep), + "distinct" => BorrowedToken::Keyword(noir_token::Keyword::Distinct), + "else" => BorrowedToken::Keyword(noir_token::Keyword::Else), + "Field" => BorrowedToken::Keyword(noir_token::Keyword::Field), + "fn" => BorrowedToken::Keyword(noir_token::Keyword::Fn), + "for" => BorrowedToken::Keyword(noir_token::Keyword::For), + "fmtstr" => BorrowedToken::Keyword(noir_token::Keyword::FormatString), + "global" => BorrowedToken::Keyword(noir_token::Keyword::Global), + "if" => BorrowedToken::Keyword(noir_token::Keyword::If), + "impl" => BorrowedToken::Keyword(noir_token::Keyword::Impl), + "in" => BorrowedToken::Keyword(noir_token::Keyword::In), + "let" => BorrowedToken::Keyword(noir_token::Keyword::Let), + "mod" => BorrowedToken::Keyword(noir_token::Keyword::Mod), + "mut" => BorrowedToken::Keyword(noir_token::Keyword::Mut), + "pub" => BorrowedToken::Keyword(noir_token::Keyword::Pub), + "quote" => BorrowedToken::Keyword(noir_token::Keyword::Quote), + "return" => BorrowedToken::Keyword(noir_token::Keyword::Return), + "return_data" => BorrowedToken::Keyword(noir_token::Keyword::ReturnData), + "str" => BorrowedToken::Keyword(noir_token::Keyword::String), + "struct" => BorrowedToken::Keyword(noir_token::Keyword::Struct), + "trait" => BorrowedToken::Keyword(noir_token::Keyword::Trait), + "type" => BorrowedToken::Keyword(noir_token::Keyword::Type), + "unchecked" => BorrowedToken::Keyword(noir_token::Keyword::Unchecked), + "unconstrained" => BorrowedToken::Keyword(noir_token::Keyword::Unconstrained), + "use" => BorrowedToken::Keyword(noir_token::Keyword::Use), + "where" => BorrowedToken::Keyword(noir_token::Keyword::Where), + "while" => BorrowedToken::Keyword(noir_token::Keyword::While), + // bool + "true" => BorrowedToken::Bool(true), + "false" => BorrowedToken::Bool(false), + + r"[\t\r\n ]+" => BorrowedToken::Whitespace(_), + + EOF => BorrowedToken::EOF, + } +} + +pub(crate) TopLevelStatement: TopLevelStatement = { + "use" r"[\t\r\n ]+" ";" EOF => { + TopLevelStatement::Import(use_tree) + } +} + +UseTree: UseTree = { + // path::to::ident as SomeAlias + => { + let ident = prefix.pop(); + let kind = UseTreeKind::Path(ident, alias); + UseTree { prefix, kind } + }, +} + +pub(crate) Path: Path = { + "crate" "::" => { + let kind = PathKind::Crate; + let span = Span::from(lo as u32..hi as u32); + Path { segments, kind, span } + }, + + "dep" "::" => { + let kind = PathKind::Dep; + let span = Span::from(lo as u32..hi as u32); + Path { segments, kind, span } + }, + + => { + segments.insert(0, id); + let kind = PathKind::Plain; + let span = Span::from(lo as u32..hi as u32); + Path { segments, kind, span } + }, +} + +PathSegments: Vec = { + )*> => { + segments + } +} + +Alias: Ident = { + r"[\t\r\n ]+" "as" r"[\t\r\n ]+" => <>, +} + +Ident: Ident = { + => { + let token = noir_token::Token::Ident(i.to_string()); + let span = Span::from(lo as u32..hi as u32); + Ident::from_token(token, span) + }, +} + +Bool: BorrowedToken<'input> = { + "true" => BorrowedToken::Bool(true), + "false" => BorrowedToken::Bool(false), +}; + diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/errors.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/errors.rs index 43a1f96f13f9..895d4e07bbd0 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/errors.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/errors.rs @@ -110,25 +110,31 @@ impl ParserError { impl std::fmt::Display for ParserError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let reason_str: String = if self.reason.is_none() { + "".to_string() + } else { + format!("\nreason: {}", Diagnostic::from(self.clone())) + }; let mut expected = vecmap(&self.expected_tokens, ToString::to_string); expected.append(&mut vecmap(&self.expected_labels, |label| format!("{label}"))); if expected.is_empty() { - write!(f, "Unexpected {} in input", self.found) + write!(f, "Unexpected {} in input{}", self.found, reason_str) } else if expected.len() == 1 { let first = expected.first().unwrap(); let vowel = "aeiou".contains(first.chars().next().unwrap()); write!( f, - "Expected a{} {} but found {}", + "Expected a{} {} but found {}{}", if vowel { "n" } else { "" }, first, - self.found + self.found, + reason_str ) } else { let expected = expected.iter().map(ToString::to_string).collect::>().join(", "); - write!(f, "Unexpected {}, expected one of {}", self.found, expected) + write!(f, "Unexpected {}, expected one of {}{}", self.found, expected, reason_str) } } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs index ea96dee8a471..80c5f47f07b1 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs @@ -97,14 +97,14 @@ where /// Sequence the two parsers. /// Fails if the first parser fails, otherwise forces /// the second parser to succeed while logging any errors. -fn then_commit<'a, P1, P2, T1, T2: 'a>( +fn then_commit<'a, P1, P2, T1, T2>( first_parser: P1, second_parser: P2, ) -> impl NoirParser<(T1, T2)> + 'a where P1: NoirParser + 'a, P2: NoirParser + 'a, - T2: Clone + Recoverable, + T2: Clone + Recoverable + 'a, { let second_parser = skip_then_retry_until(second_parser) .map_with_span(|option, span| option.unwrap_or_else(|| Recoverable::error(span))); @@ -112,14 +112,15 @@ where first_parser.then(second_parser) } -fn then_commit_ignore<'a, P1, P2, T1: 'a, T2: 'a>( +fn then_commit_ignore<'a, P1, P2, T1, T2>( first_parser: P1, second_parser: P2, ) -> impl NoirParser + 'a where P1: NoirParser + 'a, P2: NoirParser + 'a, - T2: Clone, + T1: 'a, + T2: Clone + 'a, { let second_parser = skip_then_retry_until(second_parser); first_parser.then_ignore(second_parser) @@ -140,10 +141,10 @@ where first_parser.ignore_then(second_parser) } -fn skip_then_retry_until<'a, P, T: 'a>(parser: P) -> impl NoirParser> + 'a +fn skip_then_retry_until<'a, P, T>(parser: P) -> impl NoirParser> + 'a where P: NoirParser + 'a, - T: Clone, + T: Clone + 'a, { let terminators = [ Token::EOF, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs index 0a21465fe87e..5706c3ef12f0 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs @@ -35,7 +35,7 @@ use super::{spanned, Item, ItemKind}; use crate::ast::{ Expression, ExpressionKind, LetStatement, StatementKind, UnresolvedType, UnresolvedTypeData, }; -use crate::lexer::Lexer; +use crate::lexer::{lexer::from_spanned_token_result, Lexer}; use crate::parser::{force, ignore_then_commit, statement_recovery}; use crate::token::{Keyword, Token, TokenKind}; use crate::{ @@ -47,6 +47,7 @@ use crate::{ use chumsky::prelude::*; use iter_extended::vecmap; +use lalrpop_util::lalrpop_mod; use noirc_errors::{Span, Spanned}; mod assertion; @@ -59,6 +60,9 @@ mod primitives; mod structs; mod traits; +// synthesized by LALRPOP +lalrpop_mod!(pub noir_parser); + #[cfg(test)] mod test_helpers; @@ -77,8 +81,79 @@ pub fn parse_program(source_program: &str) -> (ParsedModule, Vec) { let (module, mut parsing_errors) = program().parse_recovery_verbose(tokens); parsing_errors.extend(lexing_errors.into_iter().map(Into::into)); + let parsed_module = module.unwrap_or(ParsedModule { items: vec![] }); + + if cfg!(feature = "experimental_parser") { + for parsed_item in &parsed_module.items { + if lalrpop_parser_supports_kind(&parsed_item.kind) { + match &parsed_item.kind { + ItemKind::Import(parsed_use_tree) => { + prototype_parse_use_tree(Some(parsed_use_tree), source_program); + } + // other kinds prevented by lalrpop_parser_supports_kind + _ => unreachable!(), + } + } + } + } + (parsed_module, parsing_errors) +} + +fn prototype_parse_use_tree(expected_use_tree_opt: Option<&UseTree>, input: &str) { + // TODO(https://github.com/noir-lang/noir/issues/4777): currently skipping + // recursive use trees, e.g. "use std::{foo, bar}" + if input.contains('{') { + return; + } + + let mut lexer = Lexer::new(input); + lexer = lexer.skip_whitespaces(false); + let mut errors = Vec::new(); + + // NOTE: this is a hack to get the references working + // => this likely means that we'll want to propagate the <'input> lifetime further into Token + let lexer_result = lexer.collect::>(); + let referenced_lexer_result = lexer_result.iter().map(from_spanned_token_result); + + let calculated = noir_parser::TopLevelStatementParser::new().parse( + input, + &mut errors, + referenced_lexer_result, + ); + + if let Some(expected_use_tree) = expected_use_tree_opt { + assert!( + calculated.is_ok(), + "calculated not Ok(_): {:?}\n\nlexer: {:?}\n\ninput: {:?}", + calculated, + lexer_result, + input + ); + + match calculated.unwrap() { + TopLevelStatement::Import(parsed_use_tree) => { + assert_eq!(expected_use_tree, &parsed_use_tree); + } + unexpected_calculated => { + panic!( + "expected a TopLevelStatement::Import, but found: {:?}", + unexpected_calculated + ) + } + } + } else { + assert!( + calculated.is_err(), + "calculated not Err(_): {:?}\n\nlexer: {:?}\n\ninput: {:?}", + calculated, + lexer_result, + input + ); + } +} - (module.unwrap_or(ParsedModule { items: vec![] }), parsing_errors) +fn lalrpop_parser_supports_kind(kind: &ItemKind) -> bool { + matches!(kind, ItemKind::Import(_)) } /// program: module EOF @@ -1512,33 +1587,53 @@ mod test { #[test] fn parse_use() { - parse_all( - use_statement(), - vec![ - "use std::hash", - "use std", - "use foo::bar as hello", - "use bar as bar", - "use foo::{}", - "use foo::{bar,}", - "use foo::{bar, hello}", - "use foo::{bar as bar2, hello}", - "use foo::{bar as bar2, hello::{foo}, nested::{foo, bar}}", - "use dep::{std::println, bar::baz}", - ], - ); + let valid_use_statements = [ + "use std::hash", + "use std", + "use foo::bar as hello", + "use bar as bar", + "use foo::{}", + "use foo::{bar,}", + "use foo::{bar, hello}", + "use foo::{bar as bar2, hello}", + "use foo::{bar as bar2, hello::{foo}, nested::{foo, bar}}", + "use dep::{std::println, bar::baz}", + ]; - parse_all_failing( - use_statement(), - vec![ - "use std as ;", - "use foobar as as;", - "use hello:: as foo;", - "use foo bar::baz", - "use foo bar::{baz}", - "use foo::{,}", - ], - ); + let invalid_use_statements = [ + "use std as ;", + "use foobar as as;", + "use hello:: as foo;", + "use foo bar::baz", + "use foo bar::{baz}", + "use foo::{,}", + ]; + + let use_statements = valid_use_statements + .into_iter() + .map(|valid_str| (valid_str, true)) + .chain(invalid_use_statements.into_iter().map(|invalid_str| (invalid_str, false))); + + for (use_statement_str, expect_valid) in use_statements { + let mut use_statement_str = use_statement_str.to_string(); + let expected_use_statement = if expect_valid { + let (result_opt, _diagnostics) = + parse_recover(&use_statement(), &use_statement_str); + use_statement_str.push(';'); + match result_opt.unwrap() { + TopLevelStatement::Import(expected_use_statement) => { + Some(expected_use_statement) + } + _ => unreachable!(), + } + } else { + let result = parse_with(&use_statement(), &use_statement_str); + assert!(result.is_err()); + None + }; + + prototype_parse_use_tree(expected_use_statement.as_ref(), &use_statement_str); + } } #[test] diff --git a/noir/noir-repo/compiler/noirc_frontend/src/tests.rs b/noir/noir-repo/compiler/noirc_frontend/src/tests.rs index c4f0a8d67ba9..e4d308fbb6b6 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/tests.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/tests.rs @@ -66,7 +66,7 @@ mod test { // Allocate a default Module for the root, giving it a ModuleId let mut modules: Arena = Arena::default(); let location = Location::new(Default::default(), root_file_id); - let root = modules.insert(ModuleData::new(None, location, false)); + let root = modules.insert(ModuleData::new(None, None, location, false)); let def_map = CrateDefMap { root: LocalModuleId(root), diff --git a/noir/noir-repo/compiler/wasm/src/types/noir_artifact.ts b/noir/noir-repo/compiler/wasm/src/types/noir_artifact.ts index f241b539dc75..6ecc3ccd56f6 100644 --- a/noir/noir-repo/compiler/wasm/src/types/noir_artifact.ts +++ b/noir/noir-repo/compiler/wasm/src/types/noir_artifact.ts @@ -151,6 +151,16 @@ export interface DebugInfo { locations: Record; } +/** + * The debug information for a given program. + */ +export interface ProgramDebugInfo { + /** + * An array that maps to each function of a program. + */ + debug_infos: Array; +} + /** * Maps a file ID to its metadata for debugging purposes. */ diff --git a/noir/noir-repo/compiler/wasm/test/compiler/shared/compile.test.ts b/noir/noir-repo/compiler/wasm/test/compiler/shared/compile.test.ts index 52cef14968b6..f9e37530cbcd 100644 --- a/noir/noir-repo/compiler/wasm/test/compiler/shared/compile.test.ts +++ b/noir/noir-repo/compiler/wasm/test/compiler/shared/compile.test.ts @@ -5,6 +5,7 @@ import { ContractCompilationArtifacts, DebugFileMap, DebugInfo, + ProgramDebugInfo, NoirFunctionEntry, ProgramArtifact, ProgramCompilationArtifacts, @@ -15,7 +16,7 @@ export function shouldCompileProgramIdentically( expect: typeof Expect, timeout = 5000, ) { - it('both nargo and noir_wasm should compile identically', async () => { + it('both nargo and noir_wasm should compile program identically', async () => { // Compile! const { nargoArtifact, noirWasmArtifact } = await compileFn(); @@ -51,7 +52,7 @@ export function shouldCompileContractIdentically( expect: typeof Expect, timeout = 5000, ) { - it('both nargo and noir_wasm should compile identically', async () => { + it('both nargo and noir_wasm should compile contract identically', async () => { // Compile! const { nargoArtifact, noirWasmArtifact } = await compileFn(); @@ -90,7 +91,7 @@ function extractDebugInfos(fns: NoirFunctionEntry[]) { return fns.map((fn) => { const debugSymbols = inflateDebugSymbols(fn.debug_symbols); delete (fn as Partial).debug_symbols; - clearFileIdentifiers(debugSymbols); + clearFileIdentifiersProgram(debugSymbols); return debugSymbols; }); } @@ -113,6 +114,12 @@ function deleteContractDebugMetadata(contract: ContractArtifact) { return [extractDebugInfos(contract.functions), fileMap]; } +function clearFileIdentifiersProgram(debugSymbols: ProgramDebugInfo) { + debugSymbols.debug_infos.map((debug_info) => { + clearFileIdentifiers(debug_info); + }); +} + /** Clears file identifiers from a set of debug symbols. */ function clearFileIdentifiers(debugSymbols: DebugInfo) { for (const loc of Object.values(debugSymbols.locations)) { diff --git a/noir/noir-repo/cspell.json b/noir/noir-repo/cspell.json index 16de9757fb88..bf3040265c26 100644 --- a/noir/noir-repo/cspell.json +++ b/noir/noir-repo/cspell.json @@ -113,6 +113,7 @@ "Maddiaa", "mathbb", "memfs", + "memset", "merkle", "metas", "minreq", diff --git a/noir/noir-repo/deny.toml b/noir/noir-repo/deny.toml index eff233687e8e..db7e53cad245 100644 --- a/noir/noir-repo/deny.toml +++ b/noir/noir-repo/deny.toml @@ -58,7 +58,7 @@ allow = [ # bitmaps 2.1.0, im 15.1.0 "MPL-2.0", # Boost Software License - "BSL-1.0", + "BSL-1.0" ] # Allow 1 or more licenses on a per-crate basis, so that particular licenses @@ -70,6 +70,7 @@ exceptions = [ { allow = ["CC0-1.0"], name = "more-asserts" }, { allow = ["CC0-1.0"], name = "jsonrpc" }, { allow = ["CC0-1.0"], name = "notify" }, + { allow = ["CC0-1.0"], name = "tiny-keccak" }, { allow = ["MPL-2.0"], name = "sized-chunks" }, { allow = ["MPL-2.0"], name = "webpki-roots" }, diff --git a/noir/noir-repo/docs/docs/getting_started/tooling/index.mdx b/noir/noir-repo/docs/docs/getting_started/tooling/index.mdx deleted file mode 100644 index ac480f3c9f5e..000000000000 --- a/noir/noir-repo/docs/docs/getting_started/tooling/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Tooling -Description: This section provides information about the various tools and utilities available for Noir development. It covers the Noir playground, IDE tools, Codespaces, and community projects. -Keywords: [Noir, Development, Playground, IDE Tools, Language Service Provider, VS Code Extension, Codespaces, noir-starter, Community Projects, Awesome Noir Repository, Developer Tooling] ---- - -Noir is meant to be easy to develop with. For that reason, a number of utilities have been put together to ease the development process as much as feasible in the zero-knowledge world. - -## Playground - -The Noir playground is an easy way to test small ideas, share snippets, and integrate in other websites. You can access it at [play.noir-lang.org](https://play.noir-lang.org). - -## IDE tools - -When you install Nargo, you're also installing a Language Service Provider (LSP), which can be used by IDEs to provide syntax highlighting, codelens, warnings, and more. - -The easiest way to use these tools is by installing the [Noir VS Code extension](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir). - -## Codespaces - -Some Noir repos have leveraged Codespaces in order to ease the development process. You can visit the [noir-starter](https://github.com/noir-lang/noir-starter) for an example. - - - -## GitHub Actions - -You can use `noirup` with GitHub Actions for CI/CD and automated testing. It is as simple as -installing `noirup` and running tests in your GitHub Action `yml` file. - -See the -[config file in the Noir repo](https://github.com/TomAFrench/noir-hashes/blob/master/.github/workflows/noir.yml) for an example usage. - -## Community projects - -As an open-source project, Noir has received many contributions over time. Some of them are related with developer tooling, and you can see some of them in [Awesome Noir repository](https://github.com/noir-lang/awesome-noir#dev-tools) diff --git a/noir/noir-repo/docs/docs/how_to/debugger/_category_.json b/noir/noir-repo/docs/docs/how_to/debugger/_category_.json new file mode 100644 index 000000000000..cc2cbb1c2533 --- /dev/null +++ b/noir/noir-repo/docs/docs/how_to/debugger/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Debugging", + "position": 5, + "collapsible": true, + "collapsed": true +} diff --git a/noir/noir-repo/docs/docs/how_to/debugger/debugging_with_the_repl.md b/noir/noir-repo/docs/docs/how_to/debugger/debugging_with_the_repl.md new file mode 100644 index 000000000000..09e5bae68ad7 --- /dev/null +++ b/noir/noir-repo/docs/docs/how_to/debugger/debugging_with_the_repl.md @@ -0,0 +1,164 @@ +--- +title: Using the REPL Debugger +description: + Step by step guide on how to debug your Noir circuits with the REPL Debugger. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + REPL, + ] +sidebar_position: 1 +--- + +#### Pre-requisites + +In order to use the REPL debugger, first you need to install recent enough versions of Nargo and vscode-noir. + +## Debugging a simple circuit + +Let's debug a simple circuit: + +```rust +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` + +To start the REPL debugger, using a terminal, go to a Noir circuit's home directory. Then: + +`$ nargo debug` + +You should be seeing this in your terminal: + +``` +[main] Starting debugger +At ~/noir-examples/recursion/circuits/main/src/main.nr:1:9 + 1 -> fn main(x : Field, y : pub Field) { + 2 assert(x != y); + 3 } +> +``` + +The debugger displays the current Noir code location, and it is now waiting for us to drive it. + +Let's first take a look at the available commands. For that we'll use the `help` command. + +``` +> help +Available commands: + + opcodes display ACIR opcodes + into step into to the next opcode + next step until a new source location is reached + out step until a new source location is reached + and the current stack frame is finished + break LOCATION:OpcodeLocation add a breakpoint at an opcode location + over step until a new source location is reached + without diving into function calls + restart restart the debugging session + delete LOCATION:OpcodeLocation delete breakpoint at an opcode location + witness show witness map + witness index:u32 display a single witness from the witness map + witness index:u32 value:String update a witness with the given value + memset index:usize value:String update a memory cell with the given + value + continue continue execution until the end of the + program + vars show variable values available at this point + in execution + stacktrace display the current stack trace + memory show memory (valid when executing unconstrained code) + step step to the next ACIR opcode + +Other commands: + + help Show this help message + quit Quit repl + +``` + +Some commands operate only for unconstrained functions, such as `memory` and `memset`. If you try to use them while execution is paused at an ACIR opcode, the debugger will simply inform you that you are not executing unconstrained code: + +``` +> memory +Unconstrained VM memory not available +> +``` + +Before continuing, we can take a look at the initial witness map: + +``` +> witness +_0 = 1 +_1 = 2 +> +``` + +Cool, since `x==1`, `y==2`, and we want to check that `x != y`, our circuit should succeed. At this point we could intervene and use the witness setter command to change one of the witnesses. Let's set `y=3`, then back to 2, so we don't affect the expected result: + +``` +> witness +_0 = 1 +_1 = 2 +> witness 1 3 +_1 = 3 +> witness +_0 = 1 +_1 = 3 +> witness 1 2 +_1 = 2 +> witness +_0 = 1 +_1 = 2 +> +``` + +Now we can inspect the current state of local variables. For that we use the `vars` command. + +``` +> vars +> +``` + +We currently have no vars in context, since we are at the entry point of the program. Let's use `next` to execute until the next point in the program. + +``` +> vars +> next +At ~/noir-examples/recursion/circuits/main/src/main.nr:1:20 + 1 -> fn main(x : Field, y : pub Field) { + 2 assert(x != y); + 3 } +> vars +x:Field = 0x01 +``` + +As a result of stepping, the variable `x`, whose initial value comes from the witness map, is now in context and returned by `vars`. + +``` +> next + 1 fn main(x : Field, y : pub Field) { + 2 -> assert(x != y); + 3 } +> vars +y:Field = 0x02 +x:Field = 0x01 +``` + +Stepping again we can finally see both variables and their values. And now we can see that the next assertion should succeed. + +Let's continue to the end: + +``` +> continue +(Continuing execution...) +Finished execution +> q +[main] Circuit witness successfully solved +``` + +Upon quitting the debugger after a solved circuit, the resulting circuit witness gets saved, equivalent to what would happen if we had run the same circuit with `nargo execute`. + +We just went through the basics of debugging using Noir REPL debugger. For a comprehensive reference, check out [the reference page](../../reference/debugger/debugger_repl.md). diff --git a/noir/noir-repo/docs/docs/how_to/debugger/debugging_with_vs_code.md b/noir/noir-repo/docs/docs/how_to/debugger/debugging_with_vs_code.md new file mode 100644 index 000000000000..a5858c1a5eb5 --- /dev/null +++ b/noir/noir-repo/docs/docs/how_to/debugger/debugging_with_vs_code.md @@ -0,0 +1,68 @@ +--- +title: Using the VS Code Debugger +description: + Step by step guide on how to debug your Noir circuits with the VS Code Debugger configuration and features. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + VS Code, + IDE, + ] +sidebar_position: 0 +--- + +This guide will show you how to use VS Code with the vscode-noir extension to debug a Noir project. + +#### Pre-requisites + +- Nargo +- vscode-noir +- A Noir project with a `Nargo.toml`, `Prover.toml` and at least one Noir (`.nr`) containing an entry point function (typically `main`). + +## Running the debugger + +The easiest way to start debugging is to open the file you want to debug, and press `F5`. This will cause the debugger to launch, using your `Prover.toml` file as input. + +You should see something like this: + +![Debugger launched](@site/static/img/debugger/1-started.png) + +Let's inspect the state of the program. For that, we open VS Code's _Debug pane_. Look for this icon: + +![Debug pane icon](@site/static/img/debugger/2-icon.png) + +You will now see two categories of variables: Locals and Witness Map. + +![Debug pane expanded](@site/static/img/debugger/3-debug-pane.png) + +1. **Locals**: variables of your program. At this point in execution this section is empty, but as we step through the code it will get populated by `x`, `result`, `digest`, etc. + +2. **Witness map**: these are initially populated from your project's `Prover.toml` file. In this example, they will be used to populate `x` and `result` at the beginning of the `main` function. + +Most of the time you will probably be focusing mostly on locals, as they represent the high level state of your program. + +You might be interested in inspecting the witness map in case you are trying to solve a really low level issue in the compiler or runtime itself, so this concerns mostly advanced or niche users. + +Let's step through the program, by using the debugger buttons or their corresponding keyboard shortcuts. + +![Debugger buttons](@site/static/img/debugger/4-debugger-buttons.png) + +Now we can see in the variables pane that there's values for `digest`, `result` and `x`. + +![Inspecting locals](@site/static/img/debugger/5-assert.png) + +We can also inspect the values of variables by directly hovering on them on the code. + +![Hover locals](@site/static/img/debugger/6-hover.png) + +Let's set a break point at the `keccak256` function, so we can continue execution up to the point when it's first invoked without having to go one step at a time. + +We just need to click the to the right of the line number 18. Once the breakpoint appears, we can click the `continue` button or use its corresponding keyboard shortcut (`F5` by default). + +![Breakpoint](@site/static/img/debugger/7-break.png) + +Now we are debugging the `keccak256` function, notice the _Call Stack pane_ at the lower right. This lets us inspect the current call stack of our process. + +That covers most of the current debugger functionalities. Check out [the reference](../../reference/debugger/debugger_vscode.md) for more details on how to configure the debugger. \ No newline at end of file diff --git a/noir/noir-repo/docs/docs/how_to/merkle-proof.mdx b/noir/noir-repo/docs/docs/how_to/merkle-proof.mdx index 003c7019a939..16c425bed766 100644 --- a/noir/noir-repo/docs/docs/how_to/merkle-proof.mdx +++ b/noir/noir-repo/docs/docs/how_to/merkle-proof.mdx @@ -5,6 +5,7 @@ description: merkle tree with a specified root, at a given index. keywords: [merkle proof, merkle membership proof, Noir, rust, hash function, Pedersen, sha256, merkle tree] +sidebar_position: 4 --- Let's walk through an example of a merkle membership proof in Noir that proves that a given leaf is diff --git a/noir/noir-repo/docs/docs/noir/concepts/functions.md b/noir/noir-repo/docs/docs/noir/concepts/functions.md index 2c9bc33fdfc2..f656cdfd97a1 100644 --- a/noir/noir-repo/docs/docs/noir/concepts/functions.md +++ b/noir/noir-repo/docs/docs/noir/concepts/functions.md @@ -62,7 +62,7 @@ fn main(x : [Field]) // can't compile, has variable size fn main(....// i think you got it by now ``` -Keep in mind [tests](../../getting_started/tooling/testing.md) don't differentiate between `main` and any other function. The following snippet passes tests, but won't compile or prove: +Keep in mind [tests](../../tooling/testing.md) don't differentiate between `main` and any other function. The following snippet passes tests, but won't compile or prove: ```rust fn main(x : [Field]) { @@ -190,7 +190,7 @@ Supported attributes include: - **deprecated**: mark the function as _deprecated_. Calling the function will generate a warning: `warning: use of deprecated function` - **field**: Used to enable conditional compilation of code depending on the field size. See below for more details - **oracle**: mark the function as _oracle_; meaning it is an external unconstrained function, implemented in noir_js. See [Unconstrained](./unconstrained.md) and [NoirJS](../../reference/NoirJS/noir_js/index.md) for more details. -- **test**: mark the function as unit tests. See [Tests](../../getting_started/tooling/testing.md) for more details +- **test**: mark the function as unit tests. See [Tests](../../tooling/testing.md) for more details ### Field Attribute diff --git a/noir/noir-repo/docs/docs/noir/concepts/oracles.md b/noir/noir-repo/docs/docs/noir/concepts/oracles.md index 2e6a6818d48c..aa380b5f7b87 100644 --- a/noir/noir-repo/docs/docs/noir/concepts/oracles.md +++ b/noir/noir-repo/docs/docs/noir/concepts/oracles.md @@ -11,6 +11,12 @@ keywords: sidebar_position: 6 --- +:::note + +This is an experimental feature that is not fully documented. If you notice any outdated information or potential improvements to this page, pull request contributions are very welcome: https://github.com/noir-lang/noir + +::: + Noir has support for Oracles via RPC calls. This means Noir will make an RPC call and use the return value for proof generation. Since Oracles are not resolved by Noir, they are [`unconstrained` functions](./unconstrained.md) @@ -21,3 +27,5 @@ You can declare an Oracle through the `#[oracle()]` flag. Example: #[oracle(get_number_sequence)] unconstrained fn get_number_sequence(_size: Field) -> [Field] {} ``` + +The timeout for when using an external RPC oracle resolver can be set with the `NARGO_FOREIGN_CALL_TIMEOUT` environment variable. This timeout is in units of milliseconds. diff --git a/noir/noir-repo/docs/docs/noir/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/docs/noir/modules_packages_crates/workspaces.md index 67a1dafa3726..513497f12bf7 100644 --- a/noir/noir-repo/docs/docs/noir/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/docs/noir/modules_packages_crates/workspaces.md @@ -11,16 +11,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/docs/noir/standard_library/bigint.md b/noir/noir-repo/docs/docs/noir/standard_library/bigint.md index 9aa4fb77112c..54d791b82d3c 100644 --- a/noir/noir-repo/docs/docs/noir/standard_library/bigint.md +++ b/noir/noir-repo/docs/docs/noir/standard_library/bigint.md @@ -48,7 +48,10 @@ The available operations for each big integer are: Construct a big integer from its little-endian bytes representation. Example: ```rust + // Construct a big integer from a slice of bytes let a = Secpk1Fq::from_le_bytes(&[x, y, 0, 45, 2]); + // Construct a big integer from an array of 32 bytes + let a = Secpk1Fq::from_le_bytes_32([1;32]); ``` Sure, here's the formatted version of the remaining methods: diff --git a/noir/noir-repo/docs/docs/getting_started/tooling/_category_.json b/noir/noir-repo/docs/docs/reference/debugger/_category_.json similarity index 53% rename from noir/noir-repo/docs/docs/getting_started/tooling/_category_.json rename to noir/noir-repo/docs/docs/reference/debugger/_category_.json index 55804c03a71b..27869205ad3c 100644 --- a/noir/noir-repo/docs/docs/getting_started/tooling/_category_.json +++ b/noir/noir-repo/docs/docs/reference/debugger/_category_.json @@ -1,6 +1,6 @@ { - "position": 2, - "label": "Tooling", + "label": "Debugger", + "position": 1, "collapsible": true, "collapsed": true } diff --git a/noir/noir-repo/docs/docs/reference/debugger/debugger_known_limitations.md b/noir/noir-repo/docs/docs/reference/debugger/debugger_known_limitations.md new file mode 100644 index 000000000000..936d416ac4bc --- /dev/null +++ b/noir/noir-repo/docs/docs/reference/debugger/debugger_known_limitations.md @@ -0,0 +1,59 @@ +--- +title: Known limitations +description: + An overview of known limitations of the current version of the Noir debugger +keywords: + [ + Nargo, + Noir Debugger, + VS Code, + ] +sidebar_position: 2 +--- + +# Debugger Known Limitations + +There are currently some limits to what the debugger can observe. + +## Mutable references + +The debugger is currently blind to any state mutated via a mutable reference. For example, in: + +``` +let mut x = 1; +let y = &mut x; +*y = 2; +``` + +The update on `x` will not be observed by the debugger. That means, when running `vars` from the debugger REPL, or inspecting the _local variables_ pane in the VS Code debugger, `x` will appear with value 1 despite having executed `*y = 2;`. + +## Variables of type function or mutable references are opaque + +When inspecting variables, any variable of type `Function` or `MutableReference` will render its value as `<>` or `<>`. + +## Debugger instrumentation affects resulting ACIR + +In order to make the state of local variables observable, the debugger compiles Noir circuits interleaving foreign calls that track any mutations to them. While this works (except in the cases described above) and doesn't introduce any behavior changes, it does as a side effect produce bigger bytecode. In particular, when running the command `opcodes` on the REPL debugger, you will notice Unconstrained VM blocks that look like this: + +``` +... +5 BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [], q_c: 2 }), Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(2))], q_c: 0 })] + | outputs=[] + 5.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 5.1 | Mov { destination: RegisterIndex(3), source: RegisterIndex(1) } + 5.2 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 5.3 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 5.4 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 5.5 | Mov { destination: RegisterIndex(3), source: RegisterIndex(3) } + 5.6 | Call { location: 8 } + 5.7 | Stop + 5.8 | ForeignCall { function: "__debug_var_assign", destinations: [], inputs: [RegisterIndex(RegisterIndex(2)), RegisterIndex(RegisterIndex(3))] } +... +``` + +If you are interested in debugging/inspecting compiled ACIR without these synthetic changes, you can invoke the REPL debugger with the `--skip-instrumentation` flag or launch the VS Code debugger with the `skipConfiguration` property set to true in its launch configuration. You can find more details about those in the [Debugger REPL reference](debugger_repl.md) and the [VS Code Debugger reference](debugger_vscode.md). + +:::note +Skipping debugger instrumentation means you won't be able to inspect values of local variables. +::: + diff --git a/noir/noir-repo/docs/docs/reference/debugger/debugger_repl.md b/noir/noir-repo/docs/docs/reference/debugger/debugger_repl.md new file mode 100644 index 000000000000..46e2011304e5 --- /dev/null +++ b/noir/noir-repo/docs/docs/reference/debugger/debugger_repl.md @@ -0,0 +1,360 @@ +--- +title: REPL Debugger +description: + Noir Debugger REPL options and commands. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + REPL, + ] +sidebar_position: 1 +--- + +## Running the REPL debugger + +`nargo debug [OPTIONS] [WITNESS_NAME]` + +Runs the Noir REPL debugger. If a `WITNESS_NAME` is provided the debugger writes the resulting execution witness to a `WITNESS_NAME` file. + +### Options + +| Option | Description | +| --------------------- | ------------------------------------------------------------ | +| `-p, --prover-name ` | The name of the toml file which contains the inputs for the prover [default: Prover]| +| `--package ` | The name of the package to debug | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `-h, --help` | Print help | + +None of these options are required. + +:::note +Since the debugger starts by compiling the target package, all Noir compiler options are also available. Check out the [compiler reference](../nargo_commands.md#nargo-compile) to learn more about the compiler options. +::: + +## REPL commands + +Once the debugger is running, it accepts the following commands. + +#### `help` (h) + +Displays the menu of available commands. + +``` +> help +Available commands: + + opcodes display ACIR opcodes + into step into to the next opcode + next step until a new source location is reached + out step until a new source location is reached + and the current stack frame is finished + break LOCATION:OpcodeLocation add a breakpoint at an opcode location + over step until a new source location is reached + without diving into function calls + restart restart the debugging session + delete LOCATION:OpcodeLocation delete breakpoint at an opcode location + witness show witness map + witness index:u32 display a single witness from the witness map + witness index:u32 value:String update a witness with the given value + memset index:usize value:String update a memory cell with the given + value + continue continue execution until the end of the + program + vars show variable values available at this point + in execution + stacktrace display the current stack trace + memory show memory (valid when executing unconstrained code) value + step step to the next ACIR opcode + +Other commands: + + help Show this help message + quit Quit repl + +``` + +### Stepping through programs + +#### `next` (n) + +Step until the next Noir source code location. While other commands, such as [`into`](#into-i) and [`step`](#step-s), allow for finer grained control of the program's execution at the opcode level, `next` is source code centric. For example: + +``` +3 ... +4 fn main(x: u32) { +5 assert(entry_point(x) == 2); +6 swap_entry_point(x, x + 1); +7 -> assert(deep_entry_point(x) == 4); +8 multiple_values_entry_point(x); +9 } +``` + + +Using `next` here would cause the debugger to jump to the definition of `deep_entry_point` (if available). + +If you want to step over `deep_entry_point` and go straight to line 8, use [the `over` command](#over) instead. + +#### `over` + +Step until the next source code location, without diving into function calls. For example: + +``` +3 ... +4 fn main(x: u32) { +5 assert(entry_point(x) == 2); +6 swap_entry_point(x, x + 1); +7 -> assert(deep_entry_point(x) == 4); +8 multiple_values_entry_point(x); +9 } +``` + + +Using `over` here would cause the debugger to execute until line 8 (`multiple_values_entry_point(x);`). + +If you want to step into `deep_entry_point` instead, use [the `next` command](#next-n). + +#### `out` + +Step until the end of the current function call. For example: + +``` + 3 ... + 4 fn main(x: u32) { + 5 assert(entry_point(x) == 2); + 6 swap_entry_point(x, x + 1); + 7 -> assert(deep_entry_point(x) == 4); + 8 multiple_values_entry_point(x); + 9 } + 10 + 11 unconstrained fn returns_multiple_values(x: u32) -> (u32, u32, u32, u32) { + 12 ... + ... + 55 + 56 unconstrained fn deep_entry_point(x: u32) -> u32 { + 57 -> level_1(x + 1) + 58 } + +``` + +Running `out` here will resume execution until line 8. + +#### `step` (s) + +Skips to the next ACIR code. A compiled Noir program is a sequence of ACIR opcodes. However, an unconstrained VM opcode denotes the start of an unconstrained code block, to be executed by the unconstrained VM. For example (redacted for brevity): + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +The `->` here shows the debugger paused at an ACIR opcode: `BRILLIG`, at index 1, which denotes an unconstrained code block is about to start. + +Using the `step` command at this point would result in the debugger stopping at ACIR opcode 2, `EXPR`, skipping unconstrained computation steps. + +Use [the `into` command](#into-i) instead if you want to follow unconstrained computation step by step. + +#### `into` (i) + +Steps into the next opcode. A compiled Noir program is a sequence of ACIR opcodes. However, a BRILLIG opcode denotes the start of an unconstrained code block, to be executed by the unconstrained VM. For example (redacted for brevity): + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +The `->` here shows the debugger paused at an ACIR opcode: `BRILLIG`, at index 1, which denotes an unconstrained code block is about to start. + +Using the `into` command at this point would result in the debugger stopping at opcode 1.0, `Mov ...`, allowing the debugger user to follow unconstrained computation step by step. + +Use [the `step` command](#step-s) instead if you want to skip to the next ACIR code directly. + +#### `continue` (c) + +Continues execution until the next breakpoint, or the end of the program. + +#### `restart` (res) + +Interrupts execution, and restarts a new debugging session from scratch. + +#### `opcodes` (o) + +Display the program's ACIR opcode sequence. For example: + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +### Breakpoints + +#### `break [Opcode]` (or shorthand `b [Opcode]`) + +Sets a breakpoint on the specified opcode index. To get a list of the program opcode numbers, see [the `opcode` command](#opcodes-o). For example: + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +In this example, issuing a `break 1.2` command adds break on opcode 1.2, as denoted by the `*` character: + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | * Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +Running [the `continue` command](#continue-c) at this point would cause the debugger to execute the program until opcode 1.2. + +#### `delete [Opcode]` (or shorthand `d [Opcode]`) + +Deletes a breakpoint at an opcode location. Usage is analogous to [the `break` command](#). + +### Variable inspection + +#### vars + +Show variable values available at this point in execution. + +:::note +The ability to inspect variable values from the debugger depends on compilation to be run in a special debug instrumentation mode. This instrumentation weaves variable tracing code with the original source code. + +So variable value inspection comes at the expense of making the resulting ACIR bytecode bigger and harder to understand and optimize. + +If you find this compromise unacceptable, you can run the debugger with the flag `--skip-debug-instrumentation`. This will compile your circuit without any additional debug information, so the resulting ACIR bytecode will be identical to the one produced by standard Noir compilation. However, if you opt for this, the `vars` command will not be available while debugging. +::: + + +### Stacktrace + +#### `stacktrace` + +Displays the current stack trace. + + +### Witness map + +#### `witness` (w) + +Show witness map. For example: + +``` +_0 = 0 +_1 = 2 +_2 = 1 +``` + +#### `witness [Witness Index]` + +Display a single witness from the witness map. For example: + +``` +> witness 1 +_1 = 2 +``` + +#### `witness [Witness Index] [New value]` + +Overwrite the given index with a new value. For example: + +``` +> witness 1 3 +_1 = 3 +``` + + +### Unconstrained VM memory + +#### `memory` + +Show unconstrained VM memory state. For example: + +``` +> memory +At opcode 1.13: Store { destination_pointer: RegisterIndex(0), source: RegisterIndex(3) } +... +> registers +0 = 0 +1 = 10 +2 = 0 +3 = 1 +4 = 1 +5 = 2³² +6 = 1 +> into +At opcode 1.14: Const { destination: RegisterIndex(5), value: Value { inner: 1 } } +... +> memory +0 = 1 +> +``` + +In the example above: we start with clean memory, then step through a `Store` opcode which stores the value of register 3 (1) into the memory address stored in register 0 (0). Thus now `memory` shows memory address 0 contains value 1. + +:::note +This command is only functional while the debugger is executing unconstrained code. +::: + +#### `memset [Memory address] [New value]` + +Update a memory cell with the given value. For example: + +``` +> memory +0 = 1 +> memset 0 2 +> memory +0 = 2 +> memset 1 4 +> memory +0 = 2 +1 = 4 +> +``` + +:::note +This command is only functional while the debugger is executing unconstrained code. +::: \ No newline at end of file diff --git a/noir/noir-repo/docs/docs/reference/debugger/debugger_vscode.md b/noir/noir-repo/docs/docs/reference/debugger/debugger_vscode.md new file mode 100644 index 000000000000..c027332b3b04 --- /dev/null +++ b/noir/noir-repo/docs/docs/reference/debugger/debugger_vscode.md @@ -0,0 +1,82 @@ +--- +title: VS Code Debugger +description: + VS Code Debugger configuration and features. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + VS Code, + IDE, + ] +sidebar_position: 0 +--- + +# VS Code Noir Debugger Reference + +The Noir debugger enabled by the vscode-noir extension ships with default settings such that the most common scenario should run without any additional configuration steps. + +These defaults can nevertheless be overridden by defining a launch configuration file. This page provides a reference for the properties you can override via a launch configuration file, as well as documenting the Nargo `dap` command, which is a dependency of the VS Code Noir debugger. + + +## Creating and editing launch configuration files + +To create a launch configuration file from VS Code, open the _debug pane_, and click on _create a launch.json file_. + +![Creating a launch configuration file](@site/static/img/debugger/ref1-create-launch.png) + +A `launch.json` file will be created, populated with basic defaults. + +### Noir Debugger launch.json properties + +#### projectFolder + +_String, optional._ + +Absolute path to the Nargo project to debug. By default, it is dynamically determined by looking for the nearest `Nargo.toml` file to the active file at the moment of launching the debugger. + +#### proverName + +_String, optional._ + +Name of the prover input to use. Defaults to `Prover`, which looks for a file named `Prover.toml` at the `projectFolder`. + +#### generateAcir + +_Boolean, optional._ + +If true, generate ACIR opcodes instead of unconstrained opcodes which will be closer to release binaries but less convenient for debugging. Defaults to `false`. + +#### skipInstrumentation + +_Boolean, optional._ + +Skips variables debugging instrumentation of code, making debugging less convenient but the resulting binary smaller and closer to production. Defaults to `false`. + +:::note +Skipping instrumentation causes the debugger to be unable to inspect local variables. +::: + +## `nargo dap [OPTIONS]` + +When run without any option flags, it starts the Nargo Debug Adapter Protocol server, which acts as the debugging backend for the VS Code Noir Debugger. + +All option flags are related to preflight checks. The Debug Adapter Protocol specifies how errors are to be informed from a running DAP server, but it doesn't specify mechanisms to communicate server initialization errors between the DAP server and its client IDE. + +Thus `nargo dap` ships with a _preflight check_ mode. If flag `--preflight-check` and the rest of the `--preflight-*` flags are provided, Nargo will run the same initialization routine except it will not start the DAP server. + +`vscode-noir` will then run `nargo dap` in preflight check mode first before a debugging session starts. If the preflight check ends in error, vscode-noir will present stderr and stdout output from this process through its own Output pane in VS Code. This makes it possible for users to diagnose what pieces of configuration might be wrong or missing in case of initialization errors. + +If the preflight check succeeds, `vscode-noir` proceeds to start the DAP server normally but running `nargo dap` without any additional flags. + +### Options + +| Option | Description | +| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `--preflight-check` | If present, dap runs in preflight check mode. | +| `--preflight-project-folder ` | Absolute path to the project to debug for preflight check. | +| `--preflight-prover-name ` | Name of prover file to use for preflight check | +| `--preflight-generate-acir` | Optional. If present, compile in ACIR mode while running preflight check. | +| `--preflight-skip-instrumentation` | Optional. If present, compile without introducing debug instrumentation while running preflight check. | +| `-h, --help` | Print help. | diff --git a/noir/noir-repo/docs/docs/tooling/debugger.md b/noir/noir-repo/docs/docs/tooling/debugger.md new file mode 100644 index 000000000000..184c436068fc --- /dev/null +++ b/noir/noir-repo/docs/docs/tooling/debugger.md @@ -0,0 +1,27 @@ +--- +title: Debugger +description: Learn about the Noir Debugger, in its REPL or VS Code versions. +keywords: [Nargo, VSCode, Visual Studio Code, REPL, Debugger] +sidebar_position: 2 +--- + +# Noir Debugger + +There are currently two ways of debugging Noir programs: + +1. From VS Code, via the [vscode-noir](https://github.com/noir-lang/vscode-noir) extension. You can install it via the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir). +2. Via the REPL debugger, which ships with Nargo. + +In order to use either version of the debugger, you will need to install recent enough versions of Noir, [Nargo](../getting_started/installation) and vscode-noir: + +- Noir 0.xx +- Nargo 0.xx +- vscode-noir 0.xx + +:::info +At the moment, the debugger supports debugging binary projects, but not contracts. +::: + +We cover the VS Code Noir debugger more in depth in [its VS Code debugger how-to guide](../how_to/debugger/debugging_with_vs_code.md) and [the reference](../reference/debugger/debugger_vscode.md). + +The REPL debugger is discussed at length in [the REPL debugger how-to guide](../how_to/debugger/debugging_with_the_repl.md) and [the reference](../reference/debugger/debugger_repl.md). diff --git a/noir/noir-repo/docs/docs/getting_started/tooling/language_server.md b/noir/noir-repo/docs/docs/tooling/language_server.md similarity index 100% rename from noir/noir-repo/docs/docs/getting_started/tooling/language_server.md rename to noir/noir-repo/docs/docs/tooling/language_server.md diff --git a/noir/noir-repo/docs/docs/getting_started/tooling/testing.md b/noir/noir-repo/docs/docs/tooling/testing.md similarity index 100% rename from noir/noir-repo/docs/docs/getting_started/tooling/testing.md rename to noir/noir-repo/docs/docs/tooling/testing.md diff --git a/noir/noir-repo/docs/sidebars.js b/noir/noir-repo/docs/sidebars.js index f1e79ba9ebcf..cf7e852fed51 100644 --- a/noir/noir-repo/docs/sidebars.js +++ b/noir/noir-repo/docs/sidebars.js @@ -65,6 +65,11 @@ export default { label: 'Reference', items: [{ type: 'autogenerated', dirName: 'reference' }], }, + { + type: 'category', + label: 'Tooling', + items: [{ type: 'autogenerated', dirName: 'tooling' }], + }, { type: 'html', value: '
', diff --git a/noir/noir-repo/docs/static/img/debugger/1-started.png b/noir/noir-repo/docs/static/img/debugger/1-started.png new file mode 100644 index 000000000000..6f764d4e6012 Binary files /dev/null and b/noir/noir-repo/docs/static/img/debugger/1-started.png differ diff --git a/noir/noir-repo/docs/static/img/debugger/2-icon.png b/noir/noir-repo/docs/static/img/debugger/2-icon.png new file mode 100644 index 000000000000..31706670ccbf Binary files /dev/null and b/noir/noir-repo/docs/static/img/debugger/2-icon.png differ diff --git a/noir/noir-repo/docs/static/img/debugger/3-debug-pane.png b/noir/noir-repo/docs/static/img/debugger/3-debug-pane.png new file mode 100644 index 000000000000..24c112da96f0 Binary files /dev/null and b/noir/noir-repo/docs/static/img/debugger/3-debug-pane.png differ diff --git a/noir/noir-repo/docs/static/img/debugger/4-debugger-buttons.png b/noir/noir-repo/docs/static/img/debugger/4-debugger-buttons.png new file mode 100644 index 000000000000..64c1e05be8ab Binary files /dev/null and b/noir/noir-repo/docs/static/img/debugger/4-debugger-buttons.png differ diff --git a/noir/noir-repo/docs/static/img/debugger/5-assert.png b/noir/noir-repo/docs/static/img/debugger/5-assert.png new file mode 100644 index 000000000000..0bfed6562afb Binary files /dev/null and b/noir/noir-repo/docs/static/img/debugger/5-assert.png differ diff --git a/noir/noir-repo/docs/static/img/debugger/6-hover.png b/noir/noir-repo/docs/static/img/debugger/6-hover.png new file mode 100644 index 000000000000..20579ec461ea Binary files /dev/null and b/noir/noir-repo/docs/static/img/debugger/6-hover.png differ diff --git a/noir/noir-repo/docs/static/img/debugger/7-break.png b/noir/noir-repo/docs/static/img/debugger/7-break.png new file mode 100644 index 000000000000..aca5121d722e Binary files /dev/null and b/noir/noir-repo/docs/static/img/debugger/7-break.png differ diff --git a/noir/noir-repo/docs/static/img/debugger/debugger-intro.gif b/noir/noir-repo/docs/static/img/debugger/debugger-intro.gif new file mode 100644 index 000000000000..06e3b8535551 Binary files /dev/null and b/noir/noir-repo/docs/static/img/debugger/debugger-intro.gif differ diff --git a/noir/noir-repo/docs/static/img/debugger/ref1-create-launch.png b/noir/noir-repo/docs/static/img/debugger/ref1-create-launch.png new file mode 100644 index 000000000000..0b6cb8b3ec6e Binary files /dev/null and b/noir/noir-repo/docs/static/img/debugger/ref1-create-launch.png differ diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.17.0/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.17.0/modules_packages_crates/workspaces.md index d9ac92667c9f..8168793fc809 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.17.0/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.17.0/modules_packages_crates/workspaces.md @@ -10,16 +10,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.19.0/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.19.0/modules_packages_crates/workspaces.md index d9ac92667c9f..8168793fc809 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.19.0/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.19.0/modules_packages_crates/workspaces.md @@ -10,16 +10,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.19.1/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.19.1/modules_packages_crates/workspaces.md index d9ac92667c9f..8168793fc809 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.19.1/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.19.1/modules_packages_crates/workspaces.md @@ -10,16 +10,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.19.2/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.19.2/modules_packages_crates/workspaces.md index d9ac92667c9f..8168793fc809 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.19.2/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.19.2/modules_packages_crates/workspaces.md @@ -10,16 +10,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.19.3/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.19.3/modules_packages_crates/workspaces.md index a979ef9f0a5d..8168793fc809 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.19.3/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.19.3/modules_packages_crates/workspaces.md @@ -10,16 +10,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: @@ -36,4 +38,4 @@ default-member = "crates/a" Libraries can be defined in a workspace. Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. -Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. \ No newline at end of file +Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.19.4/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.19.4/modules_packages_crates/workspaces.md index a979ef9f0a5d..8168793fc809 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.19.4/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.19.4/modules_packages_crates/workspaces.md @@ -10,16 +10,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: @@ -36,4 +38,4 @@ default-member = "crates/a" Libraries can be defined in a workspace. Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. -Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. \ No newline at end of file +Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.22.0/noir/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.22.0/noir/modules_packages_crates/workspaces.md index 67a1dafa3726..513497f12bf7 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.22.0/noir/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.22.0/noir/modules_packages_crates/workspaces.md @@ -11,16 +11,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/workspaces.md index 67a1dafa3726..513497f12bf7 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/workspaces.md @@ -11,16 +11,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.24.0/noir/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.24.0/noir/modules_packages_crates/workspaces.md index 67a1dafa3726..513497f12bf7 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.24.0/noir/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.24.0/noir/modules_packages_crates/workspaces.md @@ -11,16 +11,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.25.0/noir/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.25.0/noir/modules_packages_crates/workspaces.md index 67a1dafa3726..513497f12bf7 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.25.0/noir/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.25.0/noir/modules_packages_crates/workspaces.md @@ -11,16 +11,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.26.0/noir/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.26.0/noir/modules_packages_crates/workspaces.md index 67a1dafa3726..513497f12bf7 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.26.0/noir/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.26.0/noir/modules_packages_crates/workspaces.md @@ -11,16 +11,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.27.0/noir/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.27.0/noir/modules_packages_crates/workspaces.md index 67a1dafa3726..513497f12bf7 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.27.0/noir/modules_packages_crates/workspaces.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.27.0/noir/modules_packages_crates/workspaces.md @@ -11,16 +11,18 @@ For a project with the following structure: ```tree ├── crates -│   ├── a -│   │   ├── Nargo.toml -│   │   └── src -│   │   └── main.nr -│   └── b -│   ├── Nargo.toml -│   └── src -│   └── main.nr -├── Nargo.toml -└── Prover.toml +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml ``` You can define a workspace in Nargo.toml like so: diff --git a/noir/noir-repo/noir_stdlib/src/bigint.nr b/noir/noir-repo/noir_stdlib/src/bigint.nr index 39ec40a1480a..ee9f8e44625c 100644 --- a/noir/noir-repo/noir_stdlib/src/bigint.nr +++ b/noir/noir-repo/noir_stdlib/src/bigint.nr @@ -32,7 +32,7 @@ impl BigInt { #[builtin(bigint_from_le_bytes)] fn from_le_bytes(bytes: [u8], modulus: [u8]) -> BigInt {} #[builtin(bigint_to_le_bytes)] - fn to_le_bytes(self) -> [u8] {} + fn to_le_bytes(self) -> [u8; 32] {} fn check_32_bytes(self: Self, other: BigInt) -> bool { let bytes = self.to_le_bytes(); @@ -47,305 +47,420 @@ impl BigInt { trait BigField { fn from_le_bytes(bytes: [u8]) -> Self; + fn from_le_bytes_32(bytes: [u8; 32]) -> Self; fn to_le_bytes(self) -> [u8]; } struct Secpk1Fq { - inner: BigInt, + array: [u8;32], } impl BigField for Secpk1Fq { fn from_le_bytes(bytes: [u8]) -> Secpk1Fq { + assert(bytes.len() <= 32); + let mut array = [0;32]; + for i in 0..bytes.len() { + array[i] = bytes[i]; + } + Secpk1Fq { + array: array, + } + } + + fn from_le_bytes_32(bytes: [u8;32]) -> Secpk1Fq { Secpk1Fq { - inner: BigInt::from_le_bytes(bytes, secpk1_fq) + array: bytes, } } + fn to_le_bytes(self) -> [u8] { - self.inner.to_le_bytes() + self.array } } impl Add for Secpk1Fq { fn add(self: Self, other: Secpk1Fq) -> Secpk1Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpk1Fq { - inner: self.inner.bigint_add(other.inner) + array: a.bigint_add(b).to_le_bytes() } } } impl Sub for Secpk1Fq { fn sub(self: Self, other: Secpk1Fq) -> Secpk1Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpk1Fq { - inner: self.inner.bigint_sub(other.inner) + array: a.bigint_sub(b).to_le_bytes() } } } impl Mul for Secpk1Fq { fn mul(self: Self, other: Secpk1Fq) -> Secpk1Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpk1Fq { - inner: self.inner.bigint_mul(other.inner) + array: a.bigint_mul(b).to_le_bytes() } - } } impl Div for Secpk1Fq { fn div(self: Self, other: Secpk1Fq) -> Secpk1Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpk1Fq { - inner: self.inner.bigint_div(other.inner) + array: a.bigint_div(b).to_le_bytes() } } } impl Eq for Secpk1Fq { fn eq(self: Self, other: Secpk1Fq) -> bool { - self.inner.check_32_bytes(other.inner) + self.array == other.array } } struct Secpk1Fr { - inner: BigInt, + array: [u8;32], } impl BigField for Secpk1Fr { fn from_le_bytes(bytes: [u8]) -> Secpk1Fr { + assert(bytes.len() <= 32); + let mut array = [0;32]; + for i in 0..bytes.len() { + array[i] = bytes[i]; + } Secpk1Fr { - inner: BigInt::from_le_bytes(bytes, secpk1_fr) + array: array, } } + + fn from_le_bytes_32(bytes: [u8;32]) -> Secpk1Fr { + Secpk1Fr { + array: bytes, + } + } + fn to_le_bytes(self) -> [u8] { - self.inner.to_le_bytes() + self.array } } impl Add for Secpk1Fr { fn add(self: Self, other: Secpk1Fr) -> Secpk1Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpk1Fr { - inner: self.inner.bigint_add(other.inner) + array: a.bigint_add(b).to_le_bytes() } } } impl Sub for Secpk1Fr { fn sub(self: Self, other: Secpk1Fr) -> Secpk1Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpk1Fr { - inner: self.inner.bigint_sub(other.inner) + array: a.bigint_sub(b).to_le_bytes() } } } impl Mul for Secpk1Fr { fn mul(self: Self, other: Secpk1Fr) -> Secpk1Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpk1Fr { - inner: self.inner.bigint_mul(other.inner) + array: a.bigint_mul(b).to_le_bytes() } - } } impl Div for Secpk1Fr { fn div(self: Self, other: Secpk1Fr) -> Secpk1Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpk1Fr { - inner: self.inner.bigint_div(other.inner) + array: a.bigint_div(b).to_le_bytes() } } } impl Eq for Secpk1Fr { fn eq(self: Self, other: Secpk1Fr) -> bool { - self.inner.check_32_bytes(other.inner) + self.array == other.array } } struct Bn254Fr { - inner: BigInt, + array: [u8;32], } impl BigField for Bn254Fr { fn from_le_bytes(bytes: [u8]) -> Bn254Fr { + assert(bytes.len() <= 32); + let mut array = [0;32]; + for i in 0..bytes.len() { + array[i] = bytes[i]; + } + Bn254Fr { + array: array, + } + } + + fn from_le_bytes_32(bytes: [u8;32]) -> Bn254Fr { Bn254Fr { - inner: BigInt::from_le_bytes(bytes, bn254_fr) + array: bytes, } } + fn to_le_bytes(self) -> [u8] { - self.inner.to_le_bytes() + self.array } } impl Add for Bn254Fr { fn add(self: Self, other: Bn254Fr) -> Bn254Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Bn254Fr { - inner: self.inner.bigint_add(other.inner) + array: a.bigint_add(b).to_le_bytes() } } } impl Sub for Bn254Fr { fn sub(self: Self, other: Bn254Fr) -> Bn254Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Bn254Fr { - inner: self.inner.bigint_sub(other.inner) + array: a.bigint_sub(b).to_le_bytes() } } } impl Mul for Bn254Fr { fn mul(self: Self, other: Bn254Fr) -> Bn254Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Bn254Fr { - inner: self.inner.bigint_mul(other.inner) + array: a.bigint_mul(b).to_le_bytes() } - } } impl Div for Bn254Fr { fn div(self: Self, other: Bn254Fr) -> Bn254Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Bn254Fr { - inner: self.inner.bigint_div(other.inner) + array: a.bigint_div(b).to_le_bytes() } } } impl Eq for Bn254Fr { fn eq(self: Self, other: Bn254Fr) -> bool { - self.inner.check_32_bytes(other.inner) + self.array == other.array } } struct Bn254Fq { - inner: BigInt, + array: [u8;32], } impl BigField for Bn254Fq { fn from_le_bytes(bytes: [u8]) -> Bn254Fq { + assert(bytes.len() <= 32); + let mut array = [0;32]; + for i in 0..bytes.len() { + array[i] = bytes[i]; + } Bn254Fq { - inner: BigInt::from_le_bytes(bytes, bn254_fq) + array: array, } } + + fn from_le_bytes_32(bytes: [u8;32]) -> Bn254Fq { + Bn254Fq { + array: bytes, + } + } + fn to_le_bytes(self) -> [u8] { - self.inner.to_le_bytes() + self.array } } impl Add for Bn254Fq { fn add(self: Self, other: Bn254Fq) -> Bn254Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Bn254Fq { - inner: self.inner.bigint_add(other.inner) + array: a.bigint_add(b).to_le_bytes() } } } impl Sub for Bn254Fq { fn sub(self: Self, other: Bn254Fq) -> Bn254Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Bn254Fq { - inner: self.inner.bigint_sub(other.inner) + array: a.bigint_sub(b).to_le_bytes() } } } impl Mul for Bn254Fq { fn mul(self: Self, other: Bn254Fq) -> Bn254Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Bn254Fq { - inner: self.inner.bigint_mul(other.inner) + array: a.bigint_mul(b).to_le_bytes() } - } } impl Div for Bn254Fq { fn div(self: Self, other: Bn254Fq) -> Bn254Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Bn254Fq { - inner: self.inner.bigint_div(other.inner) + array: a.bigint_div(b).to_le_bytes() } } } impl Eq for Bn254Fq { fn eq(self: Self, other: Bn254Fq) -> bool { - self.inner.check_32_bytes(other.inner) + self.array == other.array } } struct Secpr1Fq { - inner: BigInt, + array: [u8;32], } impl BigField for Secpr1Fq { fn from_le_bytes(bytes: [u8]) -> Secpr1Fq { + assert(bytes.len() <= 32); + let mut array = [0;32]; + for i in 0..bytes.len() { + array[i] = bytes[i]; + } + Secpr1Fq { + array: array, + } + } + + fn from_le_bytes_32(bytes: [u8;32]) -> Secpr1Fq { Secpr1Fq { - inner: BigInt::from_le_bytes(bytes, secpr1_fq) + array: bytes, } } + fn to_le_bytes(self) -> [u8] { - self.inner.to_le_bytes() + self.array } } impl Add for Secpr1Fq { fn add(self: Self, other: Secpr1Fq) -> Secpr1Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpr1Fq { - inner: self.inner.bigint_add(other.inner) + array: a.bigint_add(b).to_le_bytes() } } } impl Sub for Secpr1Fq { fn sub(self: Self, other: Secpr1Fq) -> Secpr1Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpr1Fq { - inner: self.inner.bigint_sub(other.inner) + array: a.bigint_sub(b).to_le_bytes() } } } impl Mul for Secpr1Fq { fn mul(self: Self, other: Secpr1Fq) -> Secpr1Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpr1Fq { - inner: self.inner.bigint_mul(other.inner) + array: a.bigint_mul(b).to_le_bytes() } - } } impl Div for Secpr1Fq { fn div(self: Self, other: Secpr1Fq) -> Secpr1Fq { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpr1Fq { - inner: self.inner.bigint_div(other.inner) + array: a.bigint_div(b).to_le_bytes() } } } impl Eq for Secpr1Fq { fn eq(self: Self, other: Secpr1Fq) -> bool { - self.inner.check_32_bytes(other.inner) + self.array == other.array } } struct Secpr1Fr { - inner: BigInt, + array: [u8;32], } impl BigField for Secpr1Fr { fn from_le_bytes(bytes: [u8]) -> Secpr1Fr { + assert(bytes.len() <= 32); + let mut array = [0;32]; + for i in 0..bytes.len() { + array[i] = bytes[i]; + } + Secpr1Fr { + array: array, + } + } + + fn from_le_bytes_32(bytes: [u8;32]) -> Secpr1Fr { Secpr1Fr { - inner: BigInt::from_le_bytes(bytes, secpr1_fr) + array: bytes, } } + fn to_le_bytes(self) -> [u8] { - self.inner.to_le_bytes() + self.array } } impl Add for Secpr1Fr { fn add(self: Self, other: Secpr1Fr) -> Secpr1Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpr1Fr { - inner: self.inner.bigint_add(other.inner) + array: a.bigint_add(b).to_le_bytes() } } } impl Sub for Secpr1Fr { fn sub(self: Self, other: Secpr1Fr) -> Secpr1Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpr1Fr { - inner: self.inner.bigint_sub(other.inner) + array: a.bigint_sub(b).to_le_bytes() } } } impl Mul for Secpr1Fr { fn mul(self: Self, other: Secpr1Fr) -> Secpr1Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpr1Fr { - inner: self.inner.bigint_mul(other.inner) + array: a.bigint_mul(b).to_le_bytes() } - } } impl Div for Secpr1Fr { fn div(self: Self, other: Secpr1Fr) -> Secpr1Fr { + let a = BigInt::from_le_bytes(self.array.as_slice(), secpk1_fq); + let b = BigInt::from_le_bytes(other.array.as_slice(), secpk1_fq); Secpr1Fr { - inner: self.inner.bigint_div(other.inner) + array: a.bigint_div(b).to_le_bytes() } } } impl Eq for Secpr1Fr { fn eq(self: Self, other: Secpr1Fr) -> bool { - self.inner.check_32_bytes(other.inner) + self.array == other.array } } diff --git a/noir/noir-repo/noir_stdlib/src/collections/bounded_vec.nr b/noir/noir-repo/noir_stdlib/src/collections/bounded_vec.nr index 6d5fbd44247a..c789bc386eff 100644 --- a/noir/noir-repo/noir_stdlib/src/collections/bounded_vec.nr +++ b/noir/noir-repo/noir_stdlib/src/collections/bounded_vec.nr @@ -10,7 +10,7 @@ impl BoundedVec { } pub fn get(mut self: Self, index: u64) -> T { - assert(index as u64 < self.len); + assert(index < self.len); self.storage[index] } @@ -19,7 +19,7 @@ impl BoundedVec { } pub fn push(&mut self, elem: T) { - assert(self.len < MaxLen as u64, "push out of bounds"); + assert(self.len < MaxLen, "push out of bounds"); self.storage[self.len] = elem; self.len += 1; @@ -41,7 +41,7 @@ impl BoundedVec { pub fn extend_from_array(&mut self, array: [T; Len]) { let new_len = self.len + array.len(); - assert(new_len as u64 <= MaxLen as u64, "extend_from_array out of bounds"); + assert(new_len <= MaxLen, "extend_from_array out of bounds"); for i in 0..array.len() { self.storage[self.len + i] = array[i]; } @@ -50,7 +50,7 @@ impl BoundedVec { pub fn extend_from_slice(&mut self, slice: [T]) { let new_len = self.len + slice.len(); - assert(new_len as u64 <= MaxLen as u64, "extend_from_slice out of bounds"); + assert(new_len <= MaxLen, "extend_from_slice out of bounds"); for i in 0..slice.len() { self.storage[self.len + i] = slice[i]; } @@ -60,7 +60,7 @@ impl BoundedVec { pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) { let append_len = vec.len(); let new_len = self.len + append_len; - assert(new_len as u64 <= MaxLen as u64, "extend_from_bounded_vec out of bounds"); + assert(new_len <= MaxLen, "extend_from_bounded_vec out of bounds"); let mut exceeded_len = false; for i in 0..Len { @@ -73,7 +73,7 @@ impl BoundedVec { } pub fn pop(&mut self) -> T { - assert(self.len as u64 > 0); + assert(self.len > 0); self.len -= 1; let elem = self.storage[self.len]; diff --git a/noir/noir-repo/test_programs/execution_failure/fold_dyn_index_fail/Nargo.toml b/noir/noir-repo/test_programs/execution_failure/fold_dyn_index_fail/Nargo.toml new file mode 100644 index 000000000000..e49a82cf0fbb --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/fold_dyn_index_fail/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fold_dyn_index_fail" +type = "bin" +authors = [""] +compiler_version = ">=0.26.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_failure/fold_dyn_index_fail/Prover.toml b/noir/noir-repo/test_programs/execution_failure/fold_dyn_index_fail/Prover.toml new file mode 100644 index 000000000000..caf3448c56fc --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/fold_dyn_index_fail/Prover.toml @@ -0,0 +1,2 @@ +x = [104, 101, 108, 108, 111] +z = "4" diff --git a/noir/noir-repo/test_programs/execution_failure/fold_dyn_index_fail/src/main.nr b/noir/noir-repo/test_programs/execution_failure/fold_dyn_index_fail/src/main.nr new file mode 100644 index 000000000000..b12dea630b0c --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/fold_dyn_index_fail/src/main.nr @@ -0,0 +1,10 @@ +fn main(mut x: [u32; 5], z: Field) { + x[z] = 4; + dynamic_index_check(x, z + 10); +} + +#[fold] +fn dynamic_index_check(x: [u32; 5], idx: Field) { + // Dynamic index is greater than length of the array + assert(x[idx] != 0); +} diff --git a/noir/noir-repo/test_programs/execution_failure/fold_nested_brillig_assert_fail/Nargo.toml b/noir/noir-repo/test_programs/execution_failure/fold_nested_brillig_assert_fail/Nargo.toml new file mode 100644 index 000000000000..bb7d5e20dcce --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/fold_nested_brillig_assert_fail/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fold_nested_brillig_assert_fail" +type = "bin" +authors = [""] +compiler_version = ">=0.26.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_failure/fold_nested_brillig_assert_fail/Prover.toml b/noir/noir-repo/test_programs/execution_failure/fold_nested_brillig_assert_fail/Prover.toml new file mode 100644 index 000000000000..11497a473bce --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/fold_nested_brillig_assert_fail/Prover.toml @@ -0,0 +1 @@ +x = "0" diff --git a/noir/noir-repo/test_programs/execution_failure/fold_nested_brillig_assert_fail/src/main.nr b/noir/noir-repo/test_programs/execution_failure/fold_nested_brillig_assert_fail/src/main.nr new file mode 100644 index 000000000000..0a5038c179bb --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/fold_nested_brillig_assert_fail/src/main.nr @@ -0,0 +1,26 @@ +// Tests a very simple program. +// +// The features being tested is using assert on brillig that is triggered through nested ACIR calls. +// We want to make sure we get a call stack from the original call in main to the failed assert. +fn main(x: Field) { + assert(1 == fold_conditional_wrapper(x as bool)); +} + +#[fold] +fn fold_conditional_wrapper(x: bool) -> Field { + fold_conditional(x) +} + +#[fold] +fn fold_conditional(x: bool) -> Field { + conditional_wrapper(x) +} + +unconstrained fn conditional_wrapper(x: bool) -> Field { + conditional(x) +} + +unconstrained fn conditional(x: bool) -> Field { + assert(x); + 1 +} diff --git a/noir/noir-repo/test_programs/execution_success/bigint/src/main.nr b/noir/noir-repo/test_programs/execution_success/bigint/src/main.nr index db269d63ac02..5645e4e9e1b3 100644 --- a/noir/noir-repo/test_programs/execution_success/bigint/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/bigint/src/main.nr @@ -4,17 +4,51 @@ use dep::std::{bigint::Secpk1Fq, println}; fn main(mut x: [u8; 5], y: [u8; 5]) { let a = bigint::Secpk1Fq::from_le_bytes(&[x[0], x[1], x[2], x[3], x[4]]); let b = bigint::Secpk1Fq::from_le_bytes(&[y[0], y[1], y[2], y[3], y[4]]); + let mut a_be_bytes = [0; 32]; + let mut b_be_bytes = [0; 32]; + for i in 0..5 { + a_be_bytes[31-i] = x[i]; + b_be_bytes[31-i] = y[i]; + } + let a_field = dep::std::field::bytes32_to_field(a_be_bytes); + let b_field = dep::std::field::bytes32_to_field(b_be_bytes); + + // Regression for #4682 + let c = if x[0] != 0 { + test_unconstrained1(a, b) + } else { + test_unconstrained2(a, b) + }; + assert(c.array[0] == dep::std::wrapping_mul(x[0], y[0])); + let a_bytes = a.to_le_bytes(); let b_bytes = b.to_le_bytes(); for i in 0..5 { assert(a_bytes[i] == x[i]); assert(b_bytes[i] == y[i]); } + //Regression for issue #4578 + let d = a * b; + assert(d / b == a); - let d = a * b - b; - let d1 = bigint::Secpk1Fq::from_le_bytes(597243850900842442924.to_le_bytes(10)); + let d = d - b; + let mut result = [0; 32]; + let result_slice = (a_field * b_field - b_field).to_le_bytes(32); + for i in 0..32 { + result[i] = result_slice[i]; + } + let d1 = bigint::Secpk1Fq::from_le_bytes_32(result); assert(d1 == d); - // big_int_example(x[0], x[1]); + big_int_example(x[0], x[1]); +} + +fn test_unconstrained1(a: Secpk1Fq, b: Secpk1Fq) -> Secpk1Fq { + let c = a * b; + c +} +unconstrained fn test_unconstrained2(a: Secpk1Fq, b: Secpk1Fq) -> Secpk1Fq { + let c = a + b; + test_unconstrained1(a, c) } // docs:start:big_int_example diff --git a/noir/noir-repo/test_programs/execution_success/brillig_slice_input/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_slice_input/src/main.nr index 09a9d9aef9de..8403cb7d4a06 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_slice_input/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_slice_input/src/main.nr @@ -25,6 +25,9 @@ fn main() { y: 8, } ]); + let brillig_sum = sum_slice(slice); + assert_eq(brillig_sum, 55); + slice = slice.push_back([ Point { x: 15, diff --git a/noir/noir-repo/test_programs/execution_success/fold_after_inlined_calls/Nargo.toml b/noir/noir-repo/test_programs/execution_success/fold_after_inlined_calls/Nargo.toml new file mode 100644 index 000000000000..d23924af083b --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/fold_after_inlined_calls/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fold_after_inlined_calls" +type = "bin" +authors = [""] +compiler_version = ">=0.27.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/workspace/Prover.toml b/noir/noir-repo/test_programs/execution_success/fold_after_inlined_calls/Prover.toml similarity index 50% rename from noir/noir-repo/test_programs/execution_success/workspace/Prover.toml rename to noir/noir-repo/test_programs/execution_success/fold_after_inlined_calls/Prover.toml index a0397e894776..4dd6b4051592 100644 --- a/noir/noir-repo/test_programs/execution_success/workspace/Prover.toml +++ b/noir/noir-repo/test_programs/execution_success/fold_after_inlined_calls/Prover.toml @@ -1,2 +1 @@ x = "1" -y = "0" diff --git a/noir/noir-repo/test_programs/execution_success/fold_after_inlined_calls/src/main.nr b/noir/noir-repo/test_programs/execution_success/fold_after_inlined_calls/src/main.nr new file mode 100644 index 000000000000..84c81190b9b6 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/fold_after_inlined_calls/src/main.nr @@ -0,0 +1,14 @@ +fn main(x: u32) { + // We want to call a foldable function after a call to a function that is set to be inlined + assert(increment(x) == x + 1); + foo(x); +} + +#[fold] +fn foo(x: u32) { + assert(x == 1); +} + +fn increment(x: u32) -> u32 { + x + 1 +} diff --git a/noir/noir-repo/test_programs/execution_success/unit_value/Nargo.toml b/noir/noir-repo/test_programs/execution_success/unit_value/Nargo.toml new file mode 100644 index 000000000000..f7e3697a7c10 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/unit_value/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "short" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/unit_value/src/main.nr b/noir/noir-repo/test_programs/execution_success/unit_value/src/main.nr new file mode 100644 index 000000000000..f3844e03cf20 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/unit_value/src/main.nr @@ -0,0 +1,7 @@ +fn get_transaction() { + dep::std::unsafe::zeroed() +} + +fn main() { + get_transaction(); +} diff --git a/noir/noir-repo/tooling/backend_interface/src/proof_system.rs b/noir/noir-repo/tooling/backend_interface/src/proof_system.rs index 3b47a7ced3a7..fa1f82a5722d 100644 --- a/noir/noir-repo/tooling/backend_interface/src/proof_system.rs +++ b/noir/noir-repo/tooling/backend_interface/src/proof_system.rs @@ -39,16 +39,16 @@ impl Backend { InfoCommand { crs_path: self.crs_directory() }.run(binary_path) } - /// If we cannot get a valid backend, returns `ExpressionWidth::Bound { width: 3 }`` + /// If we cannot get a valid backend, returns `ExpressionWidth::Bound { width: 4 }`` /// The function also prints a message saying we could not find a backend pub fn get_backend_info_or_default(&self) -> ExpressionWidth { if let Ok(expression_width) = self.get_backend_info() { expression_width } else { warn!( - "No valid backend found, ExpressionWidth defaulting to Bounded with a width of 3" + "No valid backend found, ExpressionWidth defaulting to Bounded with a width of 4" ); - ExpressionWidth::Bounded { width: 3 } + ExpressionWidth::Bounded { width: 4 } } } diff --git a/noir/noir-repo/tooling/backend_interface/src/smart_contract.rs b/noir/noir-repo/tooling/backend_interface/src/smart_contract.rs index f6beeeb09d99..153ab52c83f8 100644 --- a/noir/noir-repo/tooling/backend_interface/src/smart_contract.rs +++ b/noir/noir-repo/tooling/backend_interface/src/smart_contract.rs @@ -51,7 +51,7 @@ mod tests { let circuit = Circuit { current_witness_index: 4, - expression_width: ExpressionWidth::Bounded { width: 3 }, + expression_width: ExpressionWidth::Bounded { width: 4 }, opcodes: vec![constraint], private_parameters: BTreeSet::from([Witness(1), Witness(2)]), public_parameters: PublicInputs::default(), @@ -59,7 +59,7 @@ mod tests { assert_messages: Default::default(), recursive: false, }; - let program = Program { functions: vec![circuit] }; + let program = Program { functions: vec![circuit], unconstrained_functions: Vec::new() }; let contract = get_mock_backend()?.eth_contract(&program)?; diff --git a/noir/noir-repo/tooling/backend_interface/test-binaries/mock_backend/src/info_cmd.rs b/noir/noir-repo/tooling/backend_interface/test-binaries/mock_backend/src/info_cmd.rs index fd8cf6021259..75a6d323e7bd 100644 --- a/noir/noir-repo/tooling/backend_interface/test-binaries/mock_backend/src/info_cmd.rs +++ b/noir/noir-repo/tooling/backend_interface/test-binaries/mock_backend/src/info_cmd.rs @@ -5,7 +5,7 @@ use std::path::PathBuf; const INFO_RESPONSE: &str = r#"{ "language": { "name": "PLONK-CSAT", - "width": 3 + "width": 4 }, "opcodes_supported": ["arithmetic", "directive", "brillig", "memory_init", "memory_op"], "black_box_functions_supported": [ diff --git a/noir/noir-repo/tooling/debugger/src/context.rs b/noir/noir-repo/tooling/debugger/src/context.rs index b211832518d4..9b535075484e 100644 --- a/noir/noir-repo/tooling/debugger/src/context.rs +++ b/noir/noir-repo/tooling/debugger/src/context.rs @@ -1,4 +1,5 @@ use crate::foreign_calls::DebugForeignCallExecutor; +use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::acir::circuit::{Circuit, Opcode, OpcodeLocation}; use acvm::acir::native_types::{Witness, WitnessMap}; use acvm::brillig_vm::brillig::ForeignCallResult; @@ -42,10 +43,17 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { debug_artifact: &'a DebugArtifact, initial_witness: WitnessMap, foreign_call_executor: Box, + unconstrained_functions: &'a [BrilligBytecode], ) -> Self { let source_to_opcodes = build_source_to_opcode_debug_mappings(debug_artifact); Self { - acvm: ACVM::new(blackbox_solver, &circuit.opcodes, initial_witness), + // TODO: need to handle brillig pointer in the debugger + acvm: ACVM::new( + blackbox_solver, + &circuit.opcodes, + initial_witness, + unconstrained_functions, + ), brillig_solver: None, foreign_call_executor, debug_artifact, @@ -331,7 +339,8 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { self.handle_foreign_call(foreign_call) } Err(err) => DebugCommandResult::Error(NargoError::ExecutionError( - ExecutionError::SolvingError(err), + // TODO: debugger does not not handle multiple acir calls + ExecutionError::SolvingError(err, None), )), } } @@ -374,7 +383,8 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { } } ACVMStatus::Failure(error) => DebugCommandResult::Error(NargoError::ExecutionError( - ExecutionError::SolvingError(error), + // TODO: debugger does not not handle multiple acir calls + ExecutionError::SolvingError(error, None), )), ACVMStatus::RequiresForeignCall(_) => { unreachable!("Unexpected pending foreign call resolution"); @@ -630,6 +640,7 @@ fn build_source_to_opcode_debug_mappings( result } +// TODO: update all debugger tests to use unconstrained brillig pointers #[cfg(test)] mod tests { use super::*; @@ -696,12 +707,14 @@ mod tests { let foreign_call_executor = Box::new(DefaultDebugForeignCallExecutor::from_artifact(true, debug_artifact)); + let brillig_funcs = &vec![]; let mut context = DebugContext::new( &StubbedBlackBoxSolver, circuit, debug_artifact, initial_witness, foreign_call_executor, + brillig_funcs, ); assert_eq!(context.get_current_opcode_location(), Some(OpcodeLocation::Acir(0))); @@ -803,12 +816,14 @@ mod tests { let foreign_call_executor = Box::new(DefaultDebugForeignCallExecutor::from_artifact(true, debug_artifact)); + let brillig_funcs = &vec![]; let mut context = DebugContext::new( &StubbedBlackBoxSolver, circuit, debug_artifact, initial_witness, foreign_call_executor, + brillig_funcs, ); // set breakpoint @@ -860,12 +875,14 @@ mod tests { let circuit = Circuit { opcodes, ..Circuit::default() }; let debug_artifact = DebugArtifact { debug_symbols: vec![], file_map: BTreeMap::new(), warnings: vec![] }; + let brillig_funcs = &vec![]; let context = DebugContext::new( &StubbedBlackBoxSolver, &circuit, &debug_artifact, WitnessMap::new(), Box::new(DefaultDebugForeignCallExecutor::new(true)), + brillig_funcs, ); assert_eq!(context.offset_opcode_location(&None, 0), (None, 0)); diff --git a/noir/noir-repo/tooling/debugger/src/dap.rs b/noir/noir-repo/tooling/debugger/src/dap.rs index ea3204ebbbc1..060945132f59 100644 --- a/noir/noir-repo/tooling/debugger/src/dap.rs +++ b/noir/noir-repo/tooling/debugger/src/dap.rs @@ -2,6 +2,7 @@ use std::collections::BTreeMap; use std::io::{Read, Write}; use std::str::FromStr; +use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::acir::circuit::{Circuit, OpcodeLocation}; use acvm::acir::native_types::WitnessMap; use acvm::BlackBoxFunctionSolver; @@ -64,6 +65,7 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { circuit: &'a Circuit, debug_artifact: &'a DebugArtifact, initial_witness: WitnessMap, + unconstrained_functions: &'a [BrilligBytecode], ) -> Self { let context = DebugContext::new( solver, @@ -71,6 +73,7 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver> DapSession<'a, R, W, B> { debug_artifact, initial_witness, Box::new(DefaultDebugForeignCallExecutor::from_artifact(true, debug_artifact)), + unconstrained_functions, ); Self { server, @@ -603,7 +606,7 @@ pub fn run_session( initial_witness: WitnessMap, ) -> Result<(), ServerError> { let debug_artifact = DebugArtifact { - debug_symbols: vec![program.debug], + debug_symbols: program.debug, file_map: program.file_map, warnings: program.warnings, }; @@ -613,6 +616,7 @@ pub fn run_session( &program.program.functions[0], &debug_artifact, initial_witness, + &program.program.unconstrained_functions, ); session.run_loop() diff --git a/noir/noir-repo/tooling/debugger/src/lib.rs b/noir/noir-repo/tooling/debugger/src/lib.rs index 4a25e3417a07..a8fc61c893f1 100644 --- a/noir/noir-repo/tooling/debugger/src/lib.rs +++ b/noir/noir-repo/tooling/debugger/src/lib.rs @@ -9,6 +9,7 @@ use std::io::{Read, Write}; use ::dap::errors::ServerError; use ::dap::server::Server; +use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::BlackBoxFunctionSolver; use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap}; @@ -22,8 +23,9 @@ pub fn debug_circuit( circuit: &Circuit, debug_artifact: DebugArtifact, initial_witness: WitnessMap, + unconstrained_functions: &[BrilligBytecode], ) -> Result, NargoError> { - repl::run(blackbox_solver, circuit, &debug_artifact, initial_witness) + repl::run(blackbox_solver, circuit, &debug_artifact, initial_witness, unconstrained_functions) } pub fn run_dap_loop( diff --git a/noir/noir-repo/tooling/debugger/src/repl.rs b/noir/noir-repo/tooling/debugger/src/repl.rs index e30d519b62e8..2a92698e5ce0 100644 --- a/noir/noir-repo/tooling/debugger/src/repl.rs +++ b/noir/noir-repo/tooling/debugger/src/repl.rs @@ -1,5 +1,6 @@ use crate::context::{DebugCommandResult, DebugContext}; +use acvm::acir::circuit::brillig::BrilligBytecode; use acvm::acir::circuit::{Circuit, Opcode, OpcodeLocation}; use acvm::acir::native_types::{Witness, WitnessMap}; use acvm::{BlackBoxFunctionSolver, FieldElement}; @@ -20,6 +21,7 @@ pub struct ReplDebugger<'a, B: BlackBoxFunctionSolver> { debug_artifact: &'a DebugArtifact, initial_witness: WitnessMap, last_result: DebugCommandResult, + unconstrained_functions: &'a [BrilligBytecode], } impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { @@ -28,6 +30,7 @@ impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { circuit: &'a Circuit, debug_artifact: &'a DebugArtifact, initial_witness: WitnessMap, + unconstrained_functions: &'a [BrilligBytecode], ) -> Self { let foreign_call_executor = Box::new(DefaultDebugForeignCallExecutor::from_artifact(true, debug_artifact)); @@ -37,6 +40,7 @@ impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { debug_artifact, initial_witness.clone(), foreign_call_executor, + unconstrained_functions, ); let last_result = if context.get_current_opcode_location().is_none() { // handle circuit with no opcodes @@ -44,7 +48,15 @@ impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { } else { DebugCommandResult::Ok }; - Self { context, blackbox_solver, circuit, debug_artifact, initial_witness, last_result } + Self { + context, + blackbox_solver, + circuit, + debug_artifact, + initial_witness, + last_result, + unconstrained_functions, + } } pub fn show_current_vm_status(&self) { @@ -271,6 +283,7 @@ impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { self.debug_artifact, self.initial_witness.clone(), foreign_call_executor, + self.unconstrained_functions, ); for opcode_location in breakpoints { self.context.add_breakpoint(opcode_location); @@ -361,9 +374,15 @@ pub fn run( circuit: &Circuit, debug_artifact: &DebugArtifact, initial_witness: WitnessMap, + unconstrained_functions: &[BrilligBytecode], ) -> Result, NargoError> { - let context = - RefCell::new(ReplDebugger::new(blackbox_solver, circuit, debug_artifact, initial_witness)); + let context = RefCell::new(ReplDebugger::new( + blackbox_solver, + circuit, + debug_artifact, + initial_witness, + unconstrained_functions, + )); let ref_context = &context; ref_context.borrow().show_current_vm_status(); diff --git a/noir/noir-repo/tooling/lsp/src/requests/profile_run.rs b/noir/noir-repo/tooling/lsp/src/requests/profile_run.rs index 897199476893..7d06bc87c851 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/profile_run.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/profile_run.rs @@ -84,9 +84,11 @@ fn on_profile_run_request_inner( let compiled_program = nargo::ops::transform_program(compiled_program, expression_width); - let span_opcodes = compiled_program.debug.count_span_opcodes(); - let debug_artifact: DebugArtifact = compiled_program.clone().into(); - opcodes_counts.extend(span_opcodes); + for function_debug in compiled_program.debug.iter() { + let span_opcodes = function_debug.count_span_opcodes(); + opcodes_counts.extend(span_opcodes); + } + let debug_artifact: DebugArtifact = compiled_program.into(); file_map.extend(debug_artifact.file_map); } @@ -94,14 +96,17 @@ fn on_profile_run_request_inner( let compiled_contract = nargo::ops::transform_contract(compiled_contract, expression_width); - let function_debug_info: Vec<_> = - compiled_contract.functions.iter().map(|func| &func.debug).cloned().collect(); - let debug_artifact: DebugArtifact = compiled_contract.into(); - file_map.extend(debug_artifact.file_map); + let function_debug_info = compiled_contract + .functions + .iter() + .flat_map(|func| &func.debug) + .collect::>(); for contract_function_debug in function_debug_info { let span_opcodes = contract_function_debug.count_span_opcodes(); opcodes_counts.extend(span_opcodes); } + let debug_artifact: DebugArtifact = compiled_contract.into(); + file_map.extend(debug_artifact.file_map); } let result = NargoProfileRunResult { file_map, opcodes_counts }; diff --git a/noir/noir-repo/tooling/lsp/src/solver.rs b/noir/noir-repo/tooling/lsp/src/solver.rs index d0acbf1aec50..0fea9b16b54a 100644 --- a/noir/noir-repo/tooling/lsp/src/solver.rs +++ b/noir/noir-repo/tooling/lsp/src/solver.rs @@ -10,7 +10,7 @@ impl BlackBoxFunctionSolver for WrapperSolver { &self, public_key_x: &acvm::FieldElement, public_key_y: &acvm::FieldElement, - signature: &[u8], + signature: &[u8; 64], message: &[u8], ) -> Result { self.0.schnorr_verify(public_key_x, public_key_y, signature, message) diff --git a/noir/noir-repo/tooling/nargo/src/artifacts/contract.rs b/noir/noir-repo/tooling/nargo/src/artifacts/contract.rs index 868fb4404fd2..83bb4b94f820 100644 --- a/noir/noir-repo/tooling/nargo/src/artifacts/contract.rs +++ b/noir/noir-repo/tooling/nargo/src/artifacts/contract.rs @@ -4,7 +4,7 @@ use noirc_driver::{CompiledContract, CompiledContractOutputs, ContractFunction}; use serde::{Deserialize, Serialize}; use noirc_driver::DebugFile; -use noirc_errors::debug_info::DebugInfo; +use noirc_errors::debug_info::ProgramDebugInfo; use std::collections::{BTreeMap, HashMap}; use fm::FileId; @@ -68,10 +68,10 @@ pub struct ContractFunctionArtifact { pub bytecode: Program, #[serde( - serialize_with = "DebugInfo::serialize_compressed_base64_json", - deserialize_with = "DebugInfo::deserialize_compressed_base64_json" + serialize_with = "ProgramDebugInfo::serialize_compressed_base64_json", + deserialize_with = "ProgramDebugInfo::deserialize_compressed_base64_json" )] - pub debug_symbols: DebugInfo, + pub debug_symbols: ProgramDebugInfo, } impl From for ContractFunctionArtifact { @@ -82,7 +82,7 @@ impl From for ContractFunctionArtifact { custom_attributes: func.custom_attributes, abi: func.abi, bytecode: func.bytecode, - debug_symbols: func.debug, + debug_symbols: ProgramDebugInfo { debug_infos: func.debug }, } } } diff --git a/noir/noir-repo/tooling/nargo/src/artifacts/debug.rs b/noir/noir-repo/tooling/nargo/src/artifacts/debug.rs index fbdf59805c9a..496896468cc2 100644 --- a/noir/noir-repo/tooling/nargo/src/artifacts/debug.rs +++ b/noir/noir-repo/tooling/nargo/src/artifacts/debug.rs @@ -121,7 +121,7 @@ impl DebugArtifact { impl From for DebugArtifact { fn from(compiled_program: CompiledProgram) -> Self { DebugArtifact { - debug_symbols: vec![compiled_program.debug], + debug_symbols: compiled_program.debug, file_map: compiled_program.file_map, warnings: compiled_program.warnings, } @@ -133,7 +133,7 @@ impl From for DebugArtifact { let all_functions_debug: Vec = compiled_artifact .functions .into_iter() - .map(|contract_function| contract_function.debug) + .flat_map(|contract_function| contract_function.debug) .collect(); DebugArtifact { diff --git a/noir/noir-repo/tooling/nargo/src/artifacts/program.rs b/noir/noir-repo/tooling/nargo/src/artifacts/program.rs index 9e660cbd3598..67ac9f53ec82 100644 --- a/noir/noir-repo/tooling/nargo/src/artifacts/program.rs +++ b/noir/noir-repo/tooling/nargo/src/artifacts/program.rs @@ -5,7 +5,7 @@ use fm::FileId; use noirc_abi::Abi; use noirc_driver::CompiledProgram; use noirc_driver::DebugFile; -use noirc_errors::debug_info::DebugInfo; +use noirc_errors::debug_info::ProgramDebugInfo; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug)] @@ -27,10 +27,10 @@ pub struct ProgramArtifact { pub bytecode: Program, #[serde( - serialize_with = "DebugInfo::serialize_compressed_base64_json", - deserialize_with = "DebugInfo::deserialize_compressed_base64_json" + serialize_with = "ProgramDebugInfo::serialize_compressed_base64_json", + deserialize_with = "ProgramDebugInfo::deserialize_compressed_base64_json" )] - pub debug_symbols: DebugInfo, + pub debug_symbols: ProgramDebugInfo, /// 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, @@ -45,7 +45,7 @@ impl From for ProgramArtifact { abi: compiled_program.abi, noir_version: compiled_program.noir_version, bytecode: compiled_program.program, - debug_symbols: compiled_program.debug, + debug_symbols: ProgramDebugInfo { debug_infos: compiled_program.debug }, file_map: compiled_program.file_map, names: compiled_program.names, } @@ -59,7 +59,7 @@ impl From for CompiledProgram { abi: program.abi, noir_version: program.noir_version, program: program.bytecode, - debug: program.debug_symbols, + debug: program.debug_symbols.debug_infos, file_map: program.file_map, warnings: vec![], names: program.names, diff --git a/noir/noir-repo/tooling/nargo/src/errors.rs b/noir/noir-repo/tooling/nargo/src/errors.rs index ff238d79a461..ac03330a7c86 100644 --- a/noir/noir-repo/tooling/nargo/src/errors.rs +++ b/noir/noir-repo/tooling/nargo/src/errors.rs @@ -1,5 +1,5 @@ use acvm::{ - acir::circuit::OpcodeLocation, + acir::circuit::{OpcodeLocation, ResolvedOpcodeLocation}, pwg::{ErrorLocation, OpcodeResolutionError}, }; use noirc_errors::{ @@ -61,13 +61,15 @@ impl NargoError { match execution_error { ExecutionError::AssertionFailed(message, _) => Some(message), - ExecutionError::SolvingError(error) => match error { + ExecutionError::SolvingError(error, _) => match error { OpcodeResolutionError::IndexOutOfBounds { .. } | OpcodeResolutionError::OpcodeNotSolvable(_) | OpcodeResolutionError::UnsatisfiedConstrain { .. } | OpcodeResolutionError::AcirMainCallAttempted { .. } | OpcodeResolutionError::AcirCallOutputsMismatch { .. } => None, - OpcodeResolutionError::BrilligFunctionFailed { message, .. } => Some(message), + OpcodeResolutionError::BrilligFunctionFailed { message, .. } => { + message.as_ref().map(|s| s.as_str()) + } OpcodeResolutionError::BlackBoxFunctionFailed(_, reason) => Some(reason), }, } @@ -77,81 +79,105 @@ impl NargoError { #[derive(Debug, Error)] pub enum ExecutionError { #[error("Failed assertion: '{}'", .0)] - AssertionFailed(String, Vec), + AssertionFailed(String, Vec), - #[error(transparent)] - SolvingError(#[from] OpcodeResolutionError), + #[error("Failed to solve program: '{}'", .0)] + SolvingError(OpcodeResolutionError, Option>), } /// Extracts the opcode locations from a nargo error. fn extract_locations_from_error( error: &ExecutionError, - debug: &DebugInfo, + debug: &[DebugInfo], ) -> Option> { let mut opcode_locations = match error { - ExecutionError::SolvingError(OpcodeResolutionError::BrilligFunctionFailed { - call_stack, - .. - }) - | ExecutionError::AssertionFailed(_, call_stack) => Some(call_stack.clone()), - ExecutionError::SolvingError(OpcodeResolutionError::IndexOutOfBounds { - opcode_location: error_location, - .. - }) - | ExecutionError::SolvingError(OpcodeResolutionError::UnsatisfiedConstrain { - opcode_location: error_location, - }) => match error_location { + ExecutionError::SolvingError( + OpcodeResolutionError::BrilligFunctionFailed { .. }, + acir_call_stack, + ) => acir_call_stack.clone(), + ExecutionError::AssertionFailed(_, call_stack) => Some(call_stack.clone()), + ExecutionError::SolvingError( + OpcodeResolutionError::IndexOutOfBounds { opcode_location: error_location, .. }, + acir_call_stack, + ) + | ExecutionError::SolvingError( + OpcodeResolutionError::UnsatisfiedConstrain { opcode_location: error_location }, + acir_call_stack, + ) => match error_location { ErrorLocation::Unresolved => { unreachable!("Cannot resolve index for unsatisfied constraint") } - ErrorLocation::Resolved(opcode_location) => Some(vec![*opcode_location]), + ErrorLocation::Resolved(_) => acir_call_stack.clone(), }, _ => None, }?; - if let Some(OpcodeLocation::Brillig { acir_index, .. }) = opcode_locations.first() { - opcode_locations.insert(0, OpcodeLocation::Acir(*acir_index)); + // Insert the top-level Acir location where the Brillig function failed + for (i, resolved_location) in opcode_locations.iter().enumerate() { + if let ResolvedOpcodeLocation { + acir_function_index, + opcode_location: OpcodeLocation::Brillig { acir_index, .. }, + } = resolved_location + { + let acir_location = ResolvedOpcodeLocation { + acir_function_index: *acir_function_index, + opcode_location: OpcodeLocation::Acir(*acir_index), + }; + + opcode_locations.insert(i, acir_location); + // Go until the first brillig opcode as that means we have the start of a Brillig call stack. + // We have to loop through the opcode locations in case we had ACIR calls + // before the brillig function failure. + break; + } } Some( opcode_locations .iter() - .flat_map(|opcode_location| debug.opcode_location(opcode_location).unwrap_or_default()) + .flat_map(|resolved_location| { + debug[resolved_location.acir_function_index] + .opcode_location(&resolved_location.opcode_location) + .unwrap_or_default() + }) .collect(), ) } -/// Tries to generate a runtime diagnostic from a nargo error. It will successfully do so if it's a runtime error with a call stack. -pub fn try_to_diagnose_runtime_error( - nargo_err: &NargoError, - debug: &DebugInfo, -) -> Option { - let execution_error = match nargo_err { - NargoError::ExecutionError(execution_error) => execution_error, - _ => return None, - }; - - let source_locations = extract_locations_from_error(execution_error, debug)?; - - // The location of the error itself will be the location at the top - // of the call stack (the last item in the Vec). - let location = source_locations.last()?; - - let message = match nargo_err { +fn extract_message_from_error(nargo_err: &NargoError) -> String { + match nargo_err { NargoError::ExecutionError(ExecutionError::AssertionFailed(message, _)) => { format!("Assertion failed: '{message}'") } NargoError::ExecutionError(ExecutionError::SolvingError( OpcodeResolutionError::IndexOutOfBounds { index, array_size, .. }, + _, )) => { format!("Index out of bounds, array has size {array_size:?}, but index was {index:?}") } NargoError::ExecutionError(ExecutionError::SolvingError( OpcodeResolutionError::UnsatisfiedConstrain { .. }, + _, )) => "Failed constraint".into(), _ => nargo_err.to_string(), - }; + } +} +/// Tries to generate a runtime diagnostic from a nargo error. It will successfully do so if it's a runtime error with a call stack. +pub fn try_to_diagnose_runtime_error( + nargo_err: &NargoError, + debug: &[DebugInfo], +) -> Option { + let source_locations = match nargo_err { + NargoError::ExecutionError(execution_error) => { + extract_locations_from_error(execution_error, debug)? + } + _ => return None, + }; + // The location of the error itself will be the location at the top + // of the call stack (the last item in the Vec). + let location = source_locations.last()?; + let message = extract_message_from_error(nargo_err); Some( CustomDiagnostic::simple_error(message, String::new(), location.span) .in_file(location.file) diff --git a/noir/noir-repo/tooling/nargo/src/ops/execute.rs b/noir/noir-repo/tooling/nargo/src/ops/execute.rs index 6d328d65119b..97584aff1507 100644 --- a/noir/noir-repo/tooling/nargo/src/ops/execute.rs +++ b/noir/noir-repo/tooling/nargo/src/ops/execute.rs @@ -1,4 +1,5 @@ -use acvm::acir::circuit::Program; +use acvm::acir::circuit::brillig::BrilligBytecode; +use acvm::acir::circuit::{OpcodeLocation, Program, ResolvedOpcodeLocation}; use acvm::acir::native_types::WitnessStack; use acvm::brillig_vm::brillig::ForeignCallResult; use acvm::pwg::{ACVMStatus, ErrorLocation, OpcodeNotSolvable, OpcodeResolutionError, ACVM}; @@ -12,25 +13,41 @@ use super::foreign_calls::{ForeignCallExecutor, NargoForeignCallResult}; struct ProgramExecutor<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> { functions: &'a [Circuit], + + unconstrained_functions: &'a [BrilligBytecode], + // This gets built as we run through the program looking at each function call witness_stack: WitnessStack, blackbox_solver: &'a B, foreign_call_executor: &'a mut F, + + // The Noir compiler codegens per function and call stacks are not shared across ACIR function calls. + // We must rebuild a call stack when executing a program of many circuits. + call_stack: Vec, + + // Tracks the index of the current function we are executing. + // This is used to fetch the function we want to execute + // and to resolve call stack locations across many function calls. + current_function_index: usize, } impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, B, F> { fn new( functions: &'a [Circuit], + unconstrained_functions: &'a [BrilligBytecode], blackbox_solver: &'a B, foreign_call_executor: &'a mut F, ) -> Self { ProgramExecutor { functions, + unconstrained_functions, witness_stack: WitnessStack::default(), blackbox_solver, foreign_call_executor, + call_stack: Vec::default(), + current_function_index: 0, } } @@ -39,12 +56,14 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, } #[tracing::instrument(level = "trace", skip_all)] - fn execute_circuit( - &mut self, - circuit: &Circuit, - initial_witness: WitnessMap, - ) -> Result { - let mut acvm = ACVM::new(self.blackbox_solver, &circuit.opcodes, initial_witness); + fn execute_circuit(&mut self, initial_witness: WitnessMap) -> Result { + let circuit = &self.functions[self.current_function_index]; + let mut acvm = ACVM::new( + self.blackbox_solver, + &circuit.opcodes, + initial_witness, + self.unconstrained_functions, + ); // This message should be resolved by a nargo foreign call only when we have an unsatisfied assertion. let mut assert_message: Option = None; @@ -60,9 +79,26 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, let call_stack = match &error { OpcodeResolutionError::UnsatisfiedConstrain { opcode_location: ErrorLocation::Resolved(opcode_location), - } => Some(vec![*opcode_location]), + } + | OpcodeResolutionError::IndexOutOfBounds { + opcode_location: ErrorLocation::Resolved(opcode_location), + .. + } => { + let resolved_location = ResolvedOpcodeLocation { + acir_function_index: self.current_function_index, + opcode_location: *opcode_location, + }; + self.call_stack.push(resolved_location); + Some(self.call_stack.clone()) + } OpcodeResolutionError::BrilligFunctionFailed { call_stack, .. } => { - Some(call_stack.clone()) + let brillig_call_stack = + call_stack.iter().map(|location| ResolvedOpcodeLocation { + acir_function_index: self.current_function_index, + opcode_location: *location, + }); + self.call_stack.extend(brillig_call_stack); + Some(self.call_stack.clone()) } _ => None, }; @@ -70,26 +106,35 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, return Err(NargoError::ExecutionError(match call_stack { Some(call_stack) => { // First check whether we have a runtime assertion message that should be resolved on an ACVM failure - // If we do not have a runtime assertion message, we should check whether the circuit has any hardcoded - // messages associated with a specific `OpcodeLocation`. + // If we do not have a runtime assertion message, we check wether the error is a brillig error with a user-defined message, + // and finally we should check whether the circuit has any hardcoded messages associated with a specific `OpcodeLocation`. // Otherwise return the provided opcode resolution error. if let Some(assert_message) = assert_message { ExecutionError::AssertionFailed( assert_message.to_owned(), call_stack, ) + } else if let OpcodeResolutionError::BrilligFunctionFailed { + message: Some(message), + .. + } = &error + { + ExecutionError::AssertionFailed(message.to_owned(), call_stack) } else if let Some(assert_message) = circuit.get_assert_message( - *call_stack.last().expect("Call stacks should not be empty"), + call_stack + .last() + .expect("Call stacks should not be empty") + .opcode_location, ) { ExecutionError::AssertionFailed( assert_message.to_owned(), call_stack, ) } else { - ExecutionError::SolvingError(error) + ExecutionError::SolvingError(error, Some(call_stack)) } } - None => ExecutionError::SolvingError(error), + None => ExecutionError::SolvingError(error, None), })); } ACVMStatus::RequiresForeignCall(foreign_call) => { @@ -109,10 +154,24 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, } } ACVMStatus::RequiresAcirCall(call_info) => { + // Store the parent function index whose context we are currently executing + let acir_function_caller = self.current_function_index; + // Add call opcode to the call stack with a reference to the parent function index + self.call_stack.push(ResolvedOpcodeLocation { + acir_function_index: acir_function_caller, + opcode_location: OpcodeLocation::Acir(acvm.instruction_pointer()), + }); + + // Set current function to the circuit we are about to execute + self.current_function_index = call_info.id as usize; + // Execute the ACIR call let acir_to_call = &self.functions[call_info.id as usize]; let initial_witness = call_info.initial_witness; - let call_solved_witness = - self.execute_circuit(acir_to_call, initial_witness)?; + let call_solved_witness = self.execute_circuit(initial_witness)?; + + // Set tracking index back to the parent function after ACIR call execution + self.current_function_index = acir_function_caller; + let mut call_resolved_outputs = Vec::new(); for return_witness_index in acir_to_call.return_values.indices() { if let Some(return_value) = @@ -122,6 +181,7 @@ impl<'a, B: BlackBoxFunctionSolver, F: ForeignCallExecutor> ProgramExecutor<'a, } else { return Err(ExecutionError::SolvingError( OpcodeNotSolvable::MissingAssignment(return_witness_index).into(), + None, // Missing assignment errors do not supply user-facing diagnostics so we do not need to attach a call stack ) .into()); } @@ -143,11 +203,13 @@ pub fn execute_program( blackbox_solver: &B, foreign_call_executor: &mut F, ) -> Result { - let main = &program.functions[0]; - - let mut executor = - ProgramExecutor::new(&program.functions, blackbox_solver, foreign_call_executor); - let main_witness = executor.execute_circuit(main, initial_witness)?; + let mut executor = ProgramExecutor::new( + &program.functions, + &program.unconstrained_functions, + blackbox_solver, + foreign_call_executor, + ); + let main_witness = executor.execute_circuit(initial_witness)?; executor.witness_stack.push(0, main_witness); Ok(executor.finalize()) diff --git a/noir/noir-repo/tooling/nargo/src/ops/foreign_calls.rs b/noir/noir-repo/tooling/nargo/src/ops/foreign_calls.rs index bc91929e5e7c..33767314a37d 100644 --- a/noir/noir-repo/tooling/nargo/src/ops/foreign_calls.rs +++ b/noir/noir-repo/tooling/nargo/src/ops/foreign_calls.rs @@ -167,8 +167,15 @@ pub struct DefaultForeignCallExecutor { impl DefaultForeignCallExecutor { pub fn new(show_output: bool, resolver_url: Option<&str>) -> Self { let oracle_resolver = resolver_url.map(|resolver_url| { - let transport_builder = + let mut transport_builder = Builder::new().url(resolver_url).expect("Invalid oracle resolver URL"); + + if let Some(Ok(timeout)) = + std::env::var("NARGO_FOREIGN_CALL_TIMEOUT").ok().map(|timeout| timeout.parse()) + { + let timeout_duration = std::time::Duration::from_millis(timeout); + transport_builder = transport_builder.timeout(timeout_duration); + }; Client::with_transport(transport_builder.build()) }); DefaultForeignCallExecutor { diff --git a/noir/noir-repo/tooling/nargo/src/ops/optimize.rs b/noir/noir-repo/tooling/nargo/src/ops/optimize.rs index cfaaf27ea988..a62f46963281 100644 --- a/noir/noir-repo/tooling/nargo/src/ops/optimize.rs +++ b/noir/noir-repo/tooling/nargo/src/ops/optimize.rs @@ -1,25 +1,36 @@ +use acvm::acir::circuit::Program; use iter_extended::vecmap; use noirc_driver::{CompiledContract, CompiledProgram}; - -/// TODO(https://github.com/noir-lang/noir/issues/4428): Need to update how these passes are run to account for -/// multiple ACIR functions +use noirc_errors::debug_info::DebugInfo; pub fn optimize_program(mut compiled_program: CompiledProgram) -> CompiledProgram { - let (optimized_circuit, location_map) = - acvm::compiler::optimize(std::mem::take(&mut compiled_program.program.functions[0])); - compiled_program.program.functions[0] = optimized_circuit; - compiled_program.debug.update_acir(location_map); + compiled_program.program = + optimize_program_internal(compiled_program.program, &mut compiled_program.debug); compiled_program } pub fn optimize_contract(contract: CompiledContract) -> CompiledContract { let functions = vecmap(contract.functions, |mut func| { - let (optimized_bytecode, location_map) = - acvm::compiler::optimize(std::mem::take(&mut func.bytecode.functions[0])); - func.bytecode.functions[0] = optimized_bytecode; - func.debug.update_acir(location_map); + func.bytecode = optimize_program_internal(func.bytecode, &mut func.debug); func }); CompiledContract { functions, ..contract } } + +fn optimize_program_internal(mut program: Program, debug: &mut [DebugInfo]) -> Program { + let functions = std::mem::take(&mut program.functions); + + let optimized_functions = functions + .into_iter() + .enumerate() + .map(|(i, function)| { + let (optimized_circuit, location_map) = acvm::compiler::optimize(function); + debug[i].update_acir(location_map); + optimized_circuit + }) + .collect::>(); + + program.functions = optimized_functions; + program +} diff --git a/noir/noir-repo/tooling/nargo/src/ops/test.rs b/noir/noir-repo/tooling/nargo/src/ops/test.rs index 45b1a88f99c8..b216fff827db 100644 --- a/noir/noir-repo/tooling/nargo/src/ops/test.rs +++ b/noir/noir-repo/tooling/nargo/src/ops/test.rs @@ -84,7 +84,7 @@ fn test_status_program_compile_fail(err: CompileError, test_function: &TestFunct /// passed/failed to determine the test status. fn test_status_program_compile_pass( test_function: &TestFunction, - debug: DebugInfo, + debug: Vec, circuit_execution: Result, ) -> TestStatus { let circuit_execution_err = match circuit_execution { diff --git a/noir/noir-repo/tooling/nargo/src/ops/transform.rs b/noir/noir-repo/tooling/nargo/src/ops/transform.rs index 274286a46e40..b4811bd5780d 100644 --- a/noir/noir-repo/tooling/nargo/src/ops/transform.rs +++ b/noir/noir-repo/tooling/nargo/src/ops/transform.rs @@ -1,21 +1,17 @@ -use acvm::acir::circuit::ExpressionWidth; +use acvm::acir::circuit::{ExpressionWidth, Program}; use iter_extended::vecmap; use noirc_driver::{CompiledContract, CompiledProgram}; - -/// TODO(https://github.com/noir-lang/noir/issues/4428): Need to update how these passes are run to account for -/// multiple ACIR functions +use noirc_errors::debug_info::DebugInfo; pub fn transform_program( mut compiled_program: CompiledProgram, expression_width: ExpressionWidth, ) -> CompiledProgram { - let (optimized_circuit, location_map) = acvm::compiler::compile( - std::mem::take(&mut compiled_program.program.functions[0]), + compiled_program.program = transform_program_internal( + compiled_program.program, + &mut compiled_program.debug, expression_width, ); - - compiled_program.program.functions[0] = optimized_circuit; - compiled_program.debug.update_acir(location_map); compiled_program } @@ -24,14 +20,33 @@ pub fn transform_contract( expression_width: ExpressionWidth, ) -> CompiledContract { let functions = vecmap(contract.functions, |mut func| { - let (optimized_bytecode, location_map) = acvm::compiler::compile( - std::mem::take(&mut func.bytecode.functions[0]), - expression_width, - ); - func.bytecode.functions[0] = optimized_bytecode; - func.debug.update_acir(location_map); + func.bytecode = + transform_program_internal(func.bytecode, &mut func.debug, expression_width); + func }); CompiledContract { functions, ..contract } } + +fn transform_program_internal( + mut program: Program, + debug: &mut [DebugInfo], + expression_width: ExpressionWidth, +) -> Program { + let functions = std::mem::take(&mut program.functions); + + let optimized_functions = functions + .into_iter() + .enumerate() + .map(|(i, function)| { + let (optimized_circuit, location_map) = + acvm::compiler::compile(function, expression_width); + debug[i].update_acir(location_map); + optimized_circuit + }) + .collect::>(); + + program.functions = optimized_functions; + program +} diff --git a/noir/noir-repo/tooling/nargo_cli/src/cli/debug_cmd.rs b/noir/noir-repo/tooling/nargo_cli/src/cli/debug_cmd.rs index 4f3e2886b2e0..7cb5cd7846b5 100644 --- a/noir/noir-repo/tooling/nargo_cli/src/cli/debug_cmd.rs +++ b/noir/noir-repo/tooling/nargo_cli/src/cli/debug_cmd.rs @@ -232,7 +232,7 @@ pub(crate) fn debug_program( let initial_witness = compiled_program.abi.encode(inputs_map, None)?; let debug_artifact = DebugArtifact { - debug_symbols: vec![compiled_program.debug.clone()], + debug_symbols: compiled_program.debug.clone(), file_map: compiled_program.file_map.clone(), warnings: compiled_program.warnings.clone(), }; @@ -242,6 +242,7 @@ pub(crate) fn debug_program( &compiled_program.program.functions[0], debug_artifact, initial_witness, + &compiled_program.program.unconstrained_functions, ) .map_err(CliError::from) } diff --git a/noir/noir-repo/tooling/nargo_cli/src/cli/execute_cmd.rs b/noir/noir-repo/tooling/nargo_cli/src/cli/execute_cmd.rs index 697f6d7c1ea6..a353065491f2 100644 --- a/noir/noir-repo/tooling/nargo_cli/src/cli/execute_cmd.rs +++ b/noir/noir-repo/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -149,7 +149,7 @@ pub(crate) fn execute_program( Ok(solved_witness_stack) => Ok(solved_witness_stack), Err(err) => { let debug_artifact = DebugArtifact { - debug_symbols: vec![compiled_program.debug.clone()], + debug_symbols: compiled_program.debug.clone(), file_map: compiled_program.file_map.clone(), warnings: compiled_program.warnings.clone(), }; 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 72784013e173..67825362f92d 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 @@ -97,17 +97,21 @@ pub(crate) fn run( if args.profile_info { for compiled_program in &compiled_programs { - let span_opcodes = compiled_program.debug.count_span_opcodes(); let debug_artifact = DebugArtifact::from(compiled_program.clone()); - print_span_opcodes(span_opcodes, &debug_artifact); + for function_debug in compiled_program.debug.iter() { + let span_opcodes = function_debug.count_span_opcodes(); + print_span_opcodes(span_opcodes, &debug_artifact); + } } for compiled_contract in &compiled_contracts { let debug_artifact = DebugArtifact::from(compiled_contract.clone()); let functions = &compiled_contract.functions; for contract_function in functions { - let span_opcodes = contract_function.debug.count_span_opcodes(); - print_span_opcodes(span_opcodes, &debug_artifact); + for function_debug in contract_function.debug.iter() { + let span_opcodes = function_debug.count_span_opcodes(); + print_span_opcodes(span_opcodes, &debug_artifact); + } } } } @@ -289,8 +293,11 @@ fn count_opcodes_and_gates_in_program( Ok(FunctionInfo { name: compiled_program.names[i].clone(), acir_opcodes: function.opcodes.len(), - circuit_size: backend - .get_exact_circuit_size(&Program { functions: vec![function] })?, + // Unconstrained functions do not matter to a backend circuit count so we pass nothing here + circuit_size: backend.get_exact_circuit_size(&Program { + functions: vec![function], + unconstrained_functions: Vec::new(), + })?, }) }) .collect::>()?; diff --git a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/typ.rs b/noir/noir-repo/tooling/nargo_fmt/src/rewrite/typ.rs index 922337cdb740..980d02ee5dc5 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/typ.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/rewrite/typ.rs @@ -64,6 +64,7 @@ pub(crate) fn rewrite(visitor: &FmtVisitor, _shape: Shape, typ: UnresolvedType) | UnresolvedTypeData::Expression(_) | UnresolvedTypeData::String(_) | UnresolvedTypeData::FormatString(_, _) + | UnresolvedTypeData::Code | UnresolvedTypeData::TraitAsType(_, _) => visitor.slice(typ.span.unwrap()).into(), UnresolvedTypeData::Error => unreachable!(), } diff --git a/noir/noir-repo/tooling/noir_js_backend_barretenberg/package.json b/noir/noir-repo/tooling/noir_js_backend_barretenberg/package.json index fefd2f6f8d92..438e91ff3020 100644 --- a/noir/noir-repo/tooling/noir_js_backend_barretenberg/package.json +++ b/noir/noir-repo/tooling/noir_js_backend_barretenberg/package.json @@ -57,4 +57,4 @@ "ts-node": "^10.9.1", "typescript": "5.4.2" } -} \ No newline at end of file +} diff --git a/noir/noir-repo/tooling/noirc_abi/src/errors.rs b/noir/noir-repo/tooling/noirc_abi/src/errors.rs index 687fecfcc1d1..4209a9e218b0 100644 --- a/noir/noir-repo/tooling/noirc_abi/src/errors.rs +++ b/noir/noir-repo/tooling/noirc_abi/src/errors.rs @@ -1,4 +1,7 @@ -use crate::{input_parser::InputValue, AbiParameter, AbiType}; +use crate::{ + input_parser::{InputTypecheckingError, InputValue}, + AbiType, +}; use acvm::acir::native_types::Witness; use thiserror::Error; @@ -38,8 +41,8 @@ impl From for InputParserError { pub enum AbiError { #[error("Received parameters not expected by ABI: {0:?}")] UnexpectedParams(Vec), - #[error("The parameter {} is expected to be a {:?} but found incompatible value {value:?}", .param.name, .param.typ)] - TypeMismatch { param: AbiParameter, value: InputValue }, + #[error("The value passed for parameter `{}` does not match the specified type:\n{0}", .0.path())] + TypeMismatch(#[from] InputTypecheckingError), #[error("ABI expects the parameter `{0}`, but this was not found")] MissingParam(String), #[error( diff --git a/noir/noir-repo/tooling/noirc_abi/src/input_parser/mod.rs b/noir/noir-repo/tooling/noirc_abi/src/input_parser/mod.rs index f66e069d487e..4cf66820b8d0 100644 --- a/noir/noir-repo/tooling/noirc_abi/src/input_parser/mod.rs +++ b/noir/noir-repo/tooling/noirc_abi/src/input_parser/mod.rs @@ -1,6 +1,7 @@ use num_bigint::{BigInt, BigUint}; use num_traits::{Num, Zero}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; +use thiserror::Error; use acvm::FieldElement; use serde::Serialize; @@ -22,63 +23,165 @@ pub enum InputValue { Struct(BTreeMap), } +#[derive(Debug, Error)] +pub enum InputTypecheckingError { + #[error("Value {value:?} does not fall within range of allowable values for a {typ:?}")] + OutsideOfValidRange { path: String, typ: AbiType, value: InputValue }, + #[error("Type {typ:?} is expected to have length {expected_length} but value {value:?} has length {actual_length}")] + LengthMismatch { + path: String, + typ: AbiType, + value: InputValue, + expected_length: usize, + actual_length: usize, + }, + #[error("Could not find value for required field `{expected_field}`. Found values for fields {found_fields:?}")] + MissingField { path: String, expected_field: String, found_fields: Vec }, + #[error("Additional unexpected field was provided for type {typ:?}. Found field named `{extra_field}`")] + UnexpectedField { path: String, typ: AbiType, extra_field: String }, + #[error("Type {typ:?} and value {value:?} do not match")] + IncompatibleTypes { path: String, typ: AbiType, value: InputValue }, +} + +impl InputTypecheckingError { + pub(crate) fn path(&self) -> &str { + match self { + InputTypecheckingError::OutsideOfValidRange { path, .. } + | InputTypecheckingError::LengthMismatch { path, .. } + | InputTypecheckingError::MissingField { path, .. } + | InputTypecheckingError::UnexpectedField { path, .. } + | InputTypecheckingError::IncompatibleTypes { path, .. } => path, + } + } +} + impl InputValue { /// Checks whether the ABI type matches the InputValue type - /// and also their arity - pub fn matches_abi(&self, abi_param: &AbiType) -> bool { + pub(crate) fn find_type_mismatch( + &self, + abi_param: &AbiType, + path: String, + ) -> Result<(), InputTypecheckingError> { match (self, abi_param) { - (InputValue::Field(_), AbiType::Field) => true, + (InputValue::Field(_), AbiType::Field) => Ok(()), (InputValue::Field(field_element), AbiType::Integer { width, .. }) => { - field_element.num_bits() <= *width + if field_element.num_bits() <= *width { + Ok(()) + } else { + Err(InputTypecheckingError::OutsideOfValidRange { + path, + typ: abi_param.clone(), + value: self.clone(), + }) + } } (InputValue::Field(field_element), AbiType::Boolean) => { - field_element.is_one() || field_element.is_zero() + if field_element.is_one() || field_element.is_zero() { + Ok(()) + } else { + Err(InputTypecheckingError::OutsideOfValidRange { + path, + typ: abi_param.clone(), + value: self.clone(), + }) + } } (InputValue::Vec(array_elements), AbiType::Array { length, typ, .. }) => { if array_elements.len() != *length as usize { - return false; + return Err(InputTypecheckingError::LengthMismatch { + path, + typ: abi_param.clone(), + value: self.clone(), + expected_length: *length as usize, + actual_length: array_elements.len(), + }); } // Check that all of the array's elements' values match the ABI as well. - array_elements.iter().all(|input_value| input_value.matches_abi(typ)) + for (i, element) in array_elements.iter().enumerate() { + let mut path = path.clone(); + path.push_str(&format!("[{i}]")); + + element.find_type_mismatch(typ, path)?; + } + Ok(()) } (InputValue::String(string), AbiType::String { length }) => { - string.len() == *length as usize + if string.len() == *length as usize { + Ok(()) + } else { + Err(InputTypecheckingError::LengthMismatch { + path, + typ: abi_param.clone(), + value: self.clone(), + actual_length: string.len(), + expected_length: *length as usize, + }) + } } (InputValue::Struct(map), AbiType::Struct { fields, .. }) => { - if map.len() != fields.len() { - return false; + for (field_name, field_type) in fields { + if let Some(value) = map.get(field_name) { + let mut path = path.clone(); + path.push_str(&format!(".{field_name}")); + value.find_type_mismatch(field_type, path)?; + } else { + return Err(InputTypecheckingError::MissingField { + path, + expected_field: field_name.to_string(), + found_fields: map.keys().cloned().collect(), + }); + } } - let field_types = BTreeMap::from_iter(fields.iter().cloned()); + if map.len() > fields.len() { + let expected_fields: HashSet = + fields.iter().map(|(field, _)| field.to_string()).collect(); + let extra_field = map.keys().find(|&key| !expected_fields.contains(key)).cloned().expect("`map` is larger than the expected type's `fields` so it must contain an unexpected field"); + return Err(InputTypecheckingError::UnexpectedField { + path, + typ: abi_param.clone(), + extra_field: extra_field.to_string(), + }); + } - // Check that all of the struct's fields' values match the ABI as well. - map.iter().all(|(field_name, field_value)| { - if let Some(field_type) = field_types.get(field_name) { - field_value.matches_abi(field_type) - } else { - false - } - }) + Ok(()) } (InputValue::Vec(vec_elements), AbiType::Tuple { fields }) => { if vec_elements.len() != fields.len() { - return false; + return Err(InputTypecheckingError::LengthMismatch { + path, + typ: abi_param.clone(), + value: self.clone(), + actual_length: vec_elements.len(), + expected_length: fields.len(), + }); } - - vec_elements - .iter() - .zip(fields) - .all(|(input_value, abi_param)| input_value.matches_abi(abi_param)) + // Check that all of the array's elements' values match the ABI as well. + for (i, (element, expected_typ)) in vec_elements.iter().zip(fields).enumerate() { + let mut path = path.clone(); + path.push_str(&format!(".{i}")); + element.find_type_mismatch(expected_typ, path)?; + } + Ok(()) } // All other InputValue-AbiType combinations are fundamentally incompatible. - _ => false, + _ => Err(InputTypecheckingError::IncompatibleTypes { + path, + typ: abi_param.clone(), + value: self.clone(), + }), } } + + /// Checks whether the ABI type matches the InputValue type. + pub fn matches_abi(&self, abi_param: &AbiType) -> bool { + self.find_type_mismatch(abi_param, String::new()).is_ok() + } } /// The different formats that are supported when parsing diff --git a/noir/noir-repo/tooling/noirc_abi/src/lib.rs b/noir/noir-repo/tooling/noirc_abi/src/lib.rs index 89a60b0ed260..6ad13500bdd3 100644 --- a/noir/noir-repo/tooling/noirc_abi/src/lib.rs +++ b/noir/noir-repo/tooling/noirc_abi/src/lib.rs @@ -307,15 +307,7 @@ impl Abi { .ok_or_else(|| AbiError::MissingParam(param_name.clone()))? .clone(); - if !value.matches_abi(&expected_type) { - let param = self - .parameters - .iter() - .find(|param| param.name == param_name) - .unwrap() - .clone(); - return Err(AbiError::TypeMismatch { param, value }); - } + value.find_type_mismatch(&expected_type, param_name.clone())?; Self::encode_value(value, &expected_type).map(|v| (param_name, v)) }) diff --git a/noir/noir-repo/tooling/noirc_abi_wasm/test/browser/errors.test.ts b/noir/noir-repo/tooling/noirc_abi_wasm/test/browser/errors.test.ts index 429a2d446a31..0f75ff64a3ef 100644 --- a/noir/noir-repo/tooling/noirc_abi_wasm/test/browser/errors.test.ts +++ b/noir/noir-repo/tooling/noirc_abi_wasm/test/browser/errors.test.ts @@ -9,7 +9,7 @@ it('errors when an integer input overflows', async () => { const { abi, inputs } = await import('../shared/uint_overflow'); expect(() => abiEncode(abi, inputs)).to.throw( - 'The parameter foo is expected to be a Integer { sign: Unsigned, width: 32 } but found incompatible value Field(2³⁸)', + 'The value passed for parameter `foo` does not match the specified type:\nValue Field(2³⁸) does not fall within range of allowable values for a Integer { sign: Unsigned, width: 32 }', ); }); diff --git a/noir/noir-repo/tooling/noirc_abi_wasm/test/node/errors.test.ts b/noir/noir-repo/tooling/noirc_abi_wasm/test/node/errors.test.ts index 0d007e648036..fba451b4a8c8 100644 --- a/noir/noir-repo/tooling/noirc_abi_wasm/test/node/errors.test.ts +++ b/noir/noir-repo/tooling/noirc_abi_wasm/test/node/errors.test.ts @@ -5,7 +5,7 @@ it('errors when an integer input overflows', async () => { const { abi, inputs } = await import('../shared/uint_overflow'); expect(() => abiEncode(abi, inputs)).to.throw( - 'The parameter foo is expected to be a Integer { sign: Unsigned, width: 32 } but found incompatible value Field(2³⁸)', + 'The value passed for parameter `foo` does not match the specified type:\nValue Field(2³⁸) does not fall within range of allowable values for a Integer { sign: Unsigned, width: 32 }', ); }); diff --git a/scripts/attach_ebs_cache.sh b/scripts/attach_ebs_cache.sh index 7eaa988afc22..d30812b9f9b6 100755 --- a/scripts/attach_ebs_cache.sh +++ b/scripts/attach_ebs_cache.sh @@ -8,7 +8,28 @@ AVAILABILITY_ZONE="us-east-2a" VOLUME_TYPE="gp2" INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id) -# TODO also mount various other aspects of docker image metadata +# Check if someone else is doing this +if [ -f /run/.ebs-cache-mounted ] ; then + MAX_WAIT_TIME=300 # Maximum wait time in seconds + WAIT_INTERVAL=10 # Interval between checks in seconds + elapsed_time=0 + # Check for existing mount, assume we can continue if existing + while ! mount | grep -q "/var/lib/docker type ext4"; do + echo "Someone already marked as mounting, waiting for them..." + if [ $elapsed_time -ge $MAX_WAIT_TIME ]; then + echo "Cache mount did not become available within $MAX_WAIT_TIME seconds... race condition?" + exit 1 + fi + + sleep $WAIT_INTERVAL + elapsed_time=$((elapsed_time + WAIT_INTERVAL)) + done + echo "Detected existing mount, continuing..." + exit 0 +fi + +# Mark to prevent race conditions +touch /run/.ebs-cache-mounted # Check for existing mount, assume we can continue if existing if mount | grep -q "/var/lib/docker/volumes type ext4"; then @@ -57,7 +78,6 @@ while [ "$(aws ec2 describe-volumes \ --volume-ids $VOLUME_ID \ --query "Volumes[0].State" \ --output text)" != "available" ]; do - sleep 1 if [ $elapsed_time -ge $MAX_WAIT_TIME ]; then echo "Volume $VOLUME_ID did not become available within $MAX_WAIT_TIME seconds." exit 1 diff --git a/scripts/earthly-ci b/scripts/earthly-ci new file mode 100755 index 000000000000..43eeb9b17aa8 --- /dev/null +++ b/scripts/earthly-ci @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# A wrapper for Earthly that is meant to caught signs of known intermittent failures and continue. +# The silver lining is if Earthly does crash, the cache can pick up the build. +set -eu -o pipefail + +# Flag to determine if -i is present +INTERACTIVE=false +# Check for -i flag in the arguments +for arg in "$@"; do + if [ "$arg" == "-i" ] || [ "$arg" == "--interactive" ]; then + INTERACTIVE=true + break + fi +done + +OUTPUT_FILE=$(mktemp) +# capture output to handle earthly edge cases +if $INTERACTIVE ; then + # don't play nice with tee if interactive + earthly $@ +elif ! earthly $@ 2>&1 | tee $OUTPUT_FILE >&2 ; then + # we try earthly once, capturing output + # if we get one of our (unfortunate) known failures, handle retries + # TODO potentially handle other intermittent errors here + if grep 'failed to get edge: inconsistent graph state' $OUTPUT_FILE >/dev/null ; then + # TODO when earthly is overloaded we sometimes get + # 'failed to solve: failed to get edge: inconsistent graph state' + echo "Got 'inconsistent graph state'. Restarting earthly. See https://github.com/earthly/earthly/issues/2454'" + earthly $@ + # TODO handle + # could not configure satellite: failed getting org: unable to authenticate: failed to execute login request: Post + else + # otherwise, propagate error + exit 1 + fi +fi diff --git a/scripts/earthly-cloud b/scripts/earthly-cloud deleted file mode 100755 index d2a0e39bc2c5..000000000000 --- a/scripts/earthly-cloud +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env bash - -# This script uses Earthly cloud satellites based on a runner type and hash of the GITHUB_ACTOR environment variable. -# ARM or x86 can be specified. -# Usage: earthly-cloud [options] -# Arguments: -# runner type: The type of runner, e.g., 'build' or 'bench'. -# architecture: The target architecture, e.g., 'arm' or 'x86'. -set -eu -o pipefail - -# Check if at least two arguments are passed -if [ $# -lt 2 ]; then - echo "Error: Insufficient arguments provided." - echo "Usage: $0 [options]" - exit 1 -fi - -RUNNER_TYPE=$1 -ARCH=$2 -shift 2 - -if [ "$ARCH" == "arm" ]; then - PLATFORM=linux/arm64 -elif [ "$ARCH" == "x86" ]; then - PLATFORM=linux/amd64 -fi - -# default sizes for build type -if [ "$RUNNER_TYPE" == "build" ] ; then - SIZE=4xlarge - NUMBER_OF_RUNNERS=2 - if [ "$ARCH" = arm ] ; then - NUMBER_OF_RUNNERS=1 - fi - # TODO why cant we set this?? - # MAX_PARALLELISM=8 -elif [ "$RUNNER_TYPE" == "bench" ] ; then - SIZE=2xlarge - NUMBER_OF_RUNNERS=1 - # MAX_PARALLELISM=1 -elif [ "$RUNNER_TYPE" == "test" ] ; then - SIZE=4xlarge - NUMBER_OF_RUNNERS=1 -fi - -# Flag to determine if -i is present -INTERACTIVE=false -# Check for -i flag in the arguments -for arg in "$@"; do - if [ "$arg" == "-i" ] || [ "$arg" == "--interactive" ]; then - INTERACTIVE=true - break - fi -done - -# we hash our GITHUB_ACTOR to pick from 1 to NUMBER_RUNNERS (inclusive) as RUNNER_ID -# this means everyone gets assigned to runners based on their user group -NAME_HASH=$(cksum <<< "$GITHUB_ACTOR" | cut -f 1 -d ' ') -RUNNER_ID=$(($NAME_HASH % $NUMBER_OF_RUNNERS + 1)) -RUNNER=$RUNNER_TYPE-$RUNNER_ID-$ARCH -earthly sat --org aztec launch --size $SIZE --platform $PLATFORM $RUNNER || true -# --remote-cache=aztecprotocol/cache:bb-native-tests -EARTHLY_FLAGS="-P --no-output --org aztec --sat $RUNNER" -OUTPUT_FILE=$(mktemp) -# capture output to handle earthly edge cases -if $INTERACTIVE ; then - # don't play nice with tee if interactive - earthly $EARTHLY_FLAGS $@ -elif ! earthly $EARTHLY_FLAGS $@ 2>&1 | tee $OUTPUT_FILE >&2 ; then - # we try earthly once, capturing output - # if we get one of our (unfortunate) known failures, handle retries - # TODO potentially handle other intermittent errors here - if grep 'failed to get edge: inconsistent graph state' $OUTPUT_FILE >/dev/null ; then - # TODO when earthly is overloaded we sometimes get - # 'failed to solve: failed to get edge: inconsistent graph state' - echo "Got 'inconsistent graph state'. Restarting earthly. See https://github.com/earthly/earthly/issues/2454'" - earthly $EARTHLY_FLAGS $@ - # TODO handle - # could not configure satellite: failed getting org: unable to authenticate: failed to execute login request: Post - else - # otherwise, propagate error - exit 1 - fi -fi diff --git a/scripts/setup_env.sh b/scripts/setup_env.sh index 97fb8fd68a18..70ecf9d7654c 100755 --- a/scripts/setup_env.sh +++ b/scripts/setup_env.sh @@ -8,6 +8,6 @@ echo FORCE_COLOR=1 >> $GITHUB_ENV echo "Logging in to Docker..." echo $1 | docker login -u aztecprotocolci --password-stdin -# Make earthly-cloud and earthly-cloud-bench scripts available +# Make earthly-ci script available echo "PATH=$(dirname $(realpath $0)):$PATH" >> $GITHUB_ENV echo "EARTHLY_CONFIG=$(git rev-parse --show-toplevel)/.github/earthly-ci-config.yml" >> $GITHUB_ENV \ No newline at end of file diff --git a/yarn-project/Earthfile b/yarn-project/Earthfile index 7659858058d8..6825755a7321 100644 --- a/yarn-project/Earthfile +++ b/yarn-project/Earthfile @@ -29,6 +29,11 @@ deps: RUN ln -s /usr/src/yarn-project/node_modules /usr/src/node_modules build: + # Prefetch targets to not wait for +deps. + BUILD ../barretenberg/cpp/+preset-release + BUILD ../noir/+nargo + BUILD ../noir-projects/+build + BUILD ../l1-contracts/+build FROM +deps RUN apt update && apt install -y jq curl perl && rm -rf /var/lib/apt/lists/* && apt-get clean @@ -82,6 +87,9 @@ all: # for use with yarn-project/end-to-end and its e2e_mode=cache option export-end-to-end: + # Prefetch targets to build in parallel. + BUILD +end-to-end + BUILD +aztec ARG EARTHLY_GIT_HASH # pushes the foundry image to local docker images FROM ../foundry/+build diff --git a/yarn-project/archiver/package.json b/yarn-project/archiver/package.json index 17e7cb0ffdff..e1de80228691 100644 --- a/yarn-project/archiver/package.json +++ b/yarn-project/archiver/package.json @@ -51,7 +51,6 @@ "@aztec/protocol-contracts": "workspace:^", "@aztec/types": "workspace:^", "debug": "^4.3.4", - "lmdb": "^2.9.2", "lodash.groupby": "^4.6.0", "lodash.omit": "^4.5.0", "tsc-watch": "^6.0.0", diff --git a/yarn-project/archiver/src/archiver/archiver.test.ts b/yarn-project/archiver/src/archiver/archiver.test.ts index 6657106ef643..eb9a9661466b 100644 --- a/yarn-project/archiver/src/archiver/archiver.test.ts +++ b/yarn-project/archiver/src/archiver/archiver.test.ts @@ -47,7 +47,7 @@ describe('Archiver', () => { let latestBlockNum = await archiver.getBlockNumber(); expect(latestBlockNum).toEqual(0); - const blocks = blockNumbers.map(x => L2Block.random(x, 4, x, x + 1, x * 2, x * 3)); + const blocks = blockNumbers.map(x => L2Block.random(x, 4, x, x + 1, 2, 2)); const publishTxs = blocks.map(block => block.body).map(makePublishTx); const rollupTxs = blocks.map(makeRollupTx); @@ -109,7 +109,7 @@ describe('Archiver', () => { expect(encryptedLogs.length).toEqual(blockNumbers.length); for (const [index, x] of blockNumbers.entries()) { - const expectedTotalNumEncryptedLogs = 4 * x * (x * 2); + const expectedTotalNumEncryptedLogs = 4 * x * 2; const totalNumEncryptedLogs = EncryptedL2BlockL2Logs.unrollLogs([encryptedLogs[index]]).length; expect(totalNumEncryptedLogs).toEqual(expectedTotalNumEncryptedLogs); } @@ -118,7 +118,7 @@ describe('Archiver', () => { expect(unencryptedLogs.length).toEqual(blockNumbers.length); blockNumbers.forEach((x, index) => { - const expectedTotalNumUnencryptedLogs = 4 * (x + 1) * (x * 3); + const expectedTotalNumUnencryptedLogs = 4 * (x + 1) * 2; const totalNumUnencryptedLogs = UnencryptedL2BlockL2Logs.unrollLogs([unencryptedLogs[index]]).length; expect(totalNumUnencryptedLogs).toEqual(expectedTotalNumUnencryptedLogs); }); @@ -141,7 +141,7 @@ describe('Archiver', () => { let latestBlockNum = await archiver.getBlockNumber(); expect(latestBlockNum).toEqual(0); - const blocks = blockNumbers.map(x => L2Block.random(x, 4, x, x + 1, x * 2, x * 3)); + const blocks = blockNumbers.map(x => L2Block.random(x, 4, x, x + 1, 2, 2)); const publishTxs = blocks.map(block => block.body).map(makePublishTx); const rollupTxs = blocks.map(makeRollupTx); diff --git a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts index 4d0feafa58e5..24ef0228b5dd 100644 --- a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts +++ b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts @@ -300,7 +300,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch describe('getUnencryptedLogs', () => { const txsPerBlock = 4; const numPublicFunctionCalls = 3; - const numUnencryptedLogs = 4; + const numUnencryptedLogs = 2; const numBlocks = 10; let blocks: DataRetrieval; diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 7658dd950293..d0bfaa8ff321 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -671,7 +671,7 @@ export class AztecNodeService implements AztecNode { throw reverted[0].revertReason; } this.log.info(`Simulated tx ${tx.getTxHash()} succeeds`); - return returns; + return returns[0]; } public setConfig(config: Partial): Promise { diff --git a/yarn-project/aztec.js/src/account_manager/deploy_account_method.ts b/yarn-project/aztec.js/src/account_manager/deploy_account_method.ts index 75a2c6bd0d18..d9ea44b96d8d 100644 --- a/yarn-project/aztec.js/src/account_manager/deploy_account_method.ts +++ b/yarn-project/aztec.js/src/account_manager/deploy_account_method.ts @@ -46,23 +46,26 @@ export class DeployAccountMethod extends DeployMethod { : feePaymentNameOrArtifact; } - protected async getInitializeFunctionCalls(options: DeployOptions): Promise { + protected override async getInitializeFunctionCalls(options: DeployOptions): Promise { const exec = await super.getInitializeFunctionCalls(options); if (options.fee && this.#feePaymentArtifact) { const { address } = this.getInstance(); + const emptyAppPayload = EntrypointPayload.fromAppExecution([]); const feePayload = await EntrypointPayload.fromFeeOptions(options?.fee); exec.calls.push({ to: address, - args: encodeArguments(this.#feePaymentArtifact, [feePayload]), + args: encodeArguments(this.#feePaymentArtifact, [emptyAppPayload, feePayload]), functionData: FunctionData.fromAbi(this.#feePaymentArtifact), }); exec.authWitnesses ??= []; exec.packedArguments ??= []; + exec.authWitnesses.push(await this.#authWitnessProvider.createAuthWit(emptyAppPayload.hash())); exec.authWitnesses.push(await this.#authWitnessProvider.createAuthWit(feePayload.hash())); + exec.packedArguments.push(...emptyAppPayload.packedArguments); exec.packedArguments.push(...feePayload.packedArguments); } diff --git a/yarn-project/aztec.js/src/account_manager/deploy_account_sent_tx.ts b/yarn-project/aztec.js/src/account_manager/deploy_account_sent_tx.ts index ad299a68b5b8..e205286e9925 100644 --- a/yarn-project/aztec.js/src/account_manager/deploy_account_sent_tx.ts +++ b/yarn-project/aztec.js/src/account_manager/deploy_account_sent_tx.ts @@ -34,7 +34,7 @@ export class DeployAccountSentTx extends SentTx { * @param opts - Options for configuring the waiting for the tx to be mined. * @returns The transaction receipt with the wallet for the deployed account contract. */ - public async wait(opts: WaitOpts = DefaultWaitOpts): Promise { + public override async wait(opts: WaitOpts = DefaultWaitOpts): Promise { const receipt = await super.wait(opts); const wallet = await this.getWalletPromise; await waitForAccountSynch(this.pxe, wallet.getCompleteAddress(), opts); diff --git a/yarn-project/aztec.js/src/account_manager/index.ts b/yarn-project/aztec.js/src/account_manager/index.ts index 43fb28a5b23d..251e7d40bb3f 100644 --- a/yarn-project/aztec.js/src/account_manager/index.ts +++ b/yarn-project/aztec.js/src/account_manager/index.ts @@ -148,7 +148,7 @@ export class AccountManager { this.accountContract.getContractArtifact(), args, 'constructor', - 'pay_init_fee', + 'entrypoint', ); } return this.deployMethod; diff --git a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts index 897bd6ba1b90..f0c2a9e35786 100644 --- a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts +++ b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts @@ -1,6 +1,6 @@ import { type FunctionCall, PackedValues, TxExecutionRequest } from '@aztec/circuit-types'; -import { type AztecAddress, FunctionData, TxContext } from '@aztec/circuits.js'; -import { type FunctionAbi, FunctionType, encodeArguments } from '@aztec/foundation/abi'; +import { type AztecAddress, FunctionData, GasSettings, TxContext } from '@aztec/circuits.js'; +import { type FunctionAbi, FunctionType, decodeReturnValues, encodeArguments } from '@aztec/foundation/abi'; import { type Wallet } from '../account/wallet.js'; import { BaseContractInteraction, type SendMethodOptions } from './base_contract_interaction.js'; @@ -13,10 +13,10 @@ export { SendMethodOptions }; * Disregarded for simulation of public functions */ export type SimulateMethodOptions = { - /** - * The sender's Aztec address. - */ + /** The sender's Aztec address. */ from?: AztecAddress; + /** Gas settings for the simulation. */ + gasSettings?: GasSettings; }; /** @@ -73,7 +73,6 @@ export class ContractFunctionInteraction extends BaseContractInteraction { * 2. It supports `unconstrained`, `private` and `public` functions * 3. For `private` execution it: * 3.a SKIPS the entrypoint and starts directly at the function - * 3.b SKIPS public execution entirely * 4. For `public` execution it: * 4.a Removes the `txRequest` value after ended simulation * 4.b Ignores the `from` in the options @@ -86,10 +85,6 @@ export class ContractFunctionInteraction extends BaseContractInteraction { return this.wallet.viewTx(this.functionDao.name, this.args, this.contractAddress, options.from); } - // TODO: If not unconstrained, we return a size 4 array of fields. - // TODO: It should instead return the correctly decoded value - // TODO: The return type here needs to be fixed! @LHerskind - if (this.functionDao.functionType == FunctionType.SECRET) { const nodeInfo = await this.wallet.getNodeInfo(); const packedArgs = PackedValues.fromValues(encodeArguments(this.functionDao, this.args)); @@ -101,14 +96,17 @@ export class ContractFunctionInteraction extends BaseContractInteraction { txContext: TxContext.empty(nodeInfo.chainId, nodeInfo.protocolVersion), packedArguments: [packedArgs], authWitnesses: [], + gasSettings: options.gasSettings ?? GasSettings.simulation(), }); - const simulatedTx = await this.pxe.simulateTx(txRequest, false, options.from ?? this.wallet.getAddress()); - return simulatedTx.privateReturnValues?.[0]; + const simulatedTx = await this.pxe.simulateTx(txRequest, true, options.from ?? this.wallet.getAddress()); + const flattened = simulatedTx.privateReturnValues; + return flattened ? decodeReturnValues(this.functionDao, flattened) : []; } else { const txRequest = await this.create(); const simulatedTx = await this.pxe.simulateTx(txRequest, true); this.txRequest = undefined; - return simulatedTx.publicReturnValues?.[0]; + const flattened = simulatedTx.publicReturnValues; + return flattened ? decodeReturnValues(this.functionDao, flattened) : []; } } } diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index 32007df8945d..54ef3025e2b1 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -189,7 +189,7 @@ export class DeployMethod extends Bas * @param options - An object containing various deployment options such as portalContract, contractAddressSalt, and from. * @returns A SentTx object that returns the receipt and the deployed contract instance. */ - public send(options: DeployOptions = {}): DeploySentTx { + public override send(options: DeployOptions = {}): DeploySentTx { const txHashPromise = super.send(options).getTxHash(); const instance = this.getInstance(options); this.log.debug( @@ -223,7 +223,7 @@ export class DeployMethod extends Bas * @param options - Deployment options. * @returns The proven tx. */ - public prove(options: DeployOptions): Promise { + public override prove(options: DeployOptions): Promise { return super.prove(options); } diff --git a/yarn-project/aztec.js/src/contract/deploy_sent_tx.ts b/yarn-project/aztec.js/src/contract/deploy_sent_tx.ts index d77150fbe7c2..b645d3dc6d24 100644 --- a/yarn-project/aztec.js/src/contract/deploy_sent_tx.ts +++ b/yarn-project/aztec.js/src/contract/deploy_sent_tx.ts @@ -53,7 +53,7 @@ export class DeploySentTx extends SentTx * @param opts - Options for configuring the waiting for the tx to be mined. * @returns The transaction receipt with the deployed contract instance. */ - public async wait(opts?: DeployedWaitOpts): Promise> { + public override async wait(opts?: DeployedWaitOpts): Promise> { const receipt = await super.wait(opts); const contract = await this.getContractObject(opts?.wallet); return { ...receipt, contract }; diff --git a/yarn-project/aztec.js/src/entrypoint/default_entrypoint.ts b/yarn-project/aztec.js/src/entrypoint/default_entrypoint.ts index 18bc21b369cd..1596a1c6c02e 100644 --- a/yarn-project/aztec.js/src/entrypoint/default_entrypoint.ts +++ b/yarn-project/aztec.js/src/entrypoint/default_entrypoint.ts @@ -1,5 +1,5 @@ import { PackedValues, TxExecutionRequest } from '@aztec/circuit-types'; -import { TxContext } from '@aztec/circuits.js'; +import { GasSettings, TxContext } from '@aztec/circuits.js'; import { type EntrypointInterface, type ExecutionRequestInit } from './entrypoint.js'; @@ -27,6 +27,7 @@ export class DefaultEntrypoint implements EntrypointInterface { txContext, [...packedArguments, entrypointPackedValues], authWitnesses, + exec.fee?.gasSettings ?? GasSettings.default(), ), ); } diff --git a/yarn-project/aztec.js/src/entrypoint/default_multi_call_entrypoint.ts b/yarn-project/aztec.js/src/entrypoint/default_multi_call_entrypoint.ts index 39501247b81e..968960c4671b 100644 --- a/yarn-project/aztec.js/src/entrypoint/default_multi_call_entrypoint.ts +++ b/yarn-project/aztec.js/src/entrypoint/default_multi_call_entrypoint.ts @@ -1,6 +1,6 @@ import { type EntrypointInterface, EntrypointPayload, type ExecutionRequestInit } from '@aztec/aztec.js/entrypoint'; import { PackedValues, TxExecutionRequest } from '@aztec/circuit-types'; -import { type AztecAddress, FunctionData, TxContext } from '@aztec/circuits.js'; +import { type AztecAddress, FunctionData, GasSettings, TxContext } from '@aztec/circuits.js'; import { type FunctionAbi, encodeArguments } from '@aztec/foundation/abi'; import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contracts/multi-call-entrypoint'; @@ -27,6 +27,7 @@ export class DefaultMultiCallEntrypoint implements EntrypointInterface { txContext: TxContext.empty(this.chainId, this.version), packedArguments: [...payload.packedArguments, ...packedArguments, entrypointPackedArgs], authWitnesses, + gasSettings: executions.fee?.gasSettings ?? GasSettings.default(), }); return Promise.resolve(txRequest); diff --git a/yarn-project/aztec.js/src/entrypoint/payload.ts b/yarn-project/aztec.js/src/entrypoint/payload.ts index acebdc4544f5..c4bfb965aaab 100644 --- a/yarn-project/aztec.js/src/entrypoint/payload.ts +++ b/yarn-project/aztec.js/src/entrypoint/payload.ts @@ -1,5 +1,5 @@ import { type FunctionCall, PackedValues, emptyFunctionCall } from '@aztec/circuit-types'; -import { Fr, GeneratorIndex } from '@aztec/circuits.js'; +import { Fr, type GasSettings, GeneratorIndex } from '@aztec/circuits.js'; import { padArrayEnd } from '@aztec/foundation/collection'; import { pedersenHash } from '@aztec/foundation/crypto'; import { type Tuple } from '@aztec/foundation/serialize'; @@ -12,8 +12,8 @@ import { type FeePaymentMethod } from '../fee/fee_payment_method.js'; export type FeeOptions = { /** The fee payment method to use */ paymentMethod: FeePaymentMethod; - /** The fee limit to pay */ - maxFee: bigint | number | Fr; + /** The gas settings */ + gasSettings: GasSettings; }; // These must match the values defined in: @@ -137,7 +137,7 @@ export class EntrypointPayload { * @returns The execution payload */ static async fromFeeOptions(feeOpts?: FeeOptions) { - const calls = feeOpts ? await feeOpts.paymentMethod.getFunctionCalls(new Fr(feeOpts.maxFee)) : []; + const calls = feeOpts ? await feeOpts.paymentMethod.getFunctionCalls(feeOpts?.gasSettings) : []; const paddedCalls = padArrayEnd(calls, emptyFunctionCall(), FEE_MAX_CALLS); return new EntrypointPayload(paddedCalls, GeneratorIndex.FEE_PAYLOAD); } diff --git a/yarn-project/aztec.js/src/fee/fee_payment_method.ts b/yarn-project/aztec.js/src/fee/fee_payment_method.ts index cc67345b2c07..62c4f0a353e1 100644 --- a/yarn-project/aztec.js/src/fee/fee_payment_method.ts +++ b/yarn-project/aztec.js/src/fee/fee_payment_method.ts @@ -1,6 +1,6 @@ import { type FunctionCall } from '@aztec/circuit-types'; +import { type GasSettings } from '@aztec/circuits.js'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; -import { type Fr } from '@aztec/foundation/fields'; /** * Holds information about how the fee for a transaction is to be paid. @@ -17,9 +17,8 @@ export interface FeePaymentMethod { /** * Creates a function call to pay the fee in the given asset. - * TODO(fees) replace maxFee with gas limits - * @param maxFee - The maximum fee to be paid in the given asset. + * @param gasSettings - The gas limits and max fees. * @returns The function call to pay the fee. */ - getFunctionCalls(maxFee: Fr): Promise; + getFunctionCalls(gasSettings: GasSettings): Promise; } diff --git a/yarn-project/aztec.js/src/fee/native_fee_payment_method.ts b/yarn-project/aztec.js/src/fee/native_fee_payment_method.ts index f1b77c2037c8..af5a9ac3b312 100644 --- a/yarn-project/aztec.js/src/fee/native_fee_payment_method.ts +++ b/yarn-project/aztec.js/src/fee/native_fee_payment_method.ts @@ -1,7 +1,6 @@ import { type FunctionCall } from '@aztec/circuit-types'; -import { type AztecAddress, FunctionData } from '@aztec/circuits.js'; +import { type AztecAddress, FunctionData, type GasSettings } from '@aztec/circuits.js'; import { FunctionSelector } from '@aztec/foundation/abi'; -import { type Fr } from '@aztec/foundation/fields'; import { getCanonicalGasTokenAddress } from '@aztec/protocol-contracts/gas-token'; import { type Wallet } from '../account/wallet.js'; @@ -47,16 +46,16 @@ export class NativeFeePaymentMethod implements FeePaymentMethod { } /** - * Creates a function call to pay the fee in gas token.. - * @param feeLimit - The maximum fee to be paid in gas token. + * Creates a function call to pay the fee in gas token. + * @param gasSettings - The gas settings. * @returns A function call */ - getFunctionCalls(feeLimit: Fr): Promise { + getFunctionCalls(gasSettings: GasSettings): Promise { return Promise.resolve([ { to: this.#gasTokenAddress, functionData: new FunctionData(FunctionSelector.fromSignature('pay_fee(Field)'), false), - args: [feeLimit], + args: [gasSettings.getFeeLimit()], }, ]); } diff --git a/yarn-project/aztec.js/src/fee/private_fee_payment_method.ts b/yarn-project/aztec.js/src/fee/private_fee_payment_method.ts index ce4e3ae12424..e6abb694172f 100644 --- a/yarn-project/aztec.js/src/fee/private_fee_payment_method.ts +++ b/yarn-project/aztec.js/src/fee/private_fee_payment_method.ts @@ -1,5 +1,5 @@ import { type FunctionCall } from '@aztec/circuit-types'; -import { FunctionData } from '@aztec/circuits.js'; +import { FunctionData, type GasSettings } from '@aztec/circuits.js'; import { computeMessageSecretHash } from '@aztec/circuits.js/hash'; import { FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; @@ -53,11 +53,12 @@ export class PrivateFeePaymentMethod implements FeePaymentMethod { /** * Creates a function call to pay the fee in the given asset. - * @param maxFee - The maximum fee to be paid in the given asset. + * @param gasSettings - The gas settings. * @returns The function call to pay the fee. */ - async getFunctionCalls(maxFee: Fr): Promise { + async getFunctionCalls(gasSettings: GasSettings): Promise { const nonce = Fr.random(); + const maxFee = gasSettings.getFeeLimit(); const messageHash = computeAuthWitMessageHash( this.paymentContract, this.wallet.getChainId(), diff --git a/yarn-project/aztec.js/src/fee/public_fee_payment_method.ts b/yarn-project/aztec.js/src/fee/public_fee_payment_method.ts index 9dbd4b416d6f..33b2430ebeeb 100644 --- a/yarn-project/aztec.js/src/fee/public_fee_payment_method.ts +++ b/yarn-project/aztec.js/src/fee/public_fee_payment_method.ts @@ -1,5 +1,5 @@ import { type FunctionCall } from '@aztec/circuit-types'; -import { FunctionData } from '@aztec/circuits.js'; +import { FunctionData, type GasSettings } from '@aztec/circuits.js'; import { FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; @@ -46,12 +46,12 @@ export class PublicFeePaymentMethod implements FeePaymentMethod { /** * Creates a function call to pay the fee in the given asset. - * @param maxFee - The maximum fee to be paid in the given asset. + * @param gasSettings - The gas settings. * @returns The function call to pay the fee. */ - getFunctionCalls(maxFee: Fr): Promise { + getFunctionCalls(gasSettings: GasSettings): Promise { const nonce = Fr.random(); - + const maxFee = gasSettings.getFeeLimit(); const messageHash = computeAuthWitMessageHash( this.paymentContract, this.wallet.getChainId(), diff --git a/yarn-project/aztec.js/src/wallet/account_wallet.ts b/yarn-project/aztec.js/src/wallet/account_wallet.ts index 40ac99864775..803d07010eba 100644 --- a/yarn-project/aztec.js/src/wallet/account_wallet.ts +++ b/yarn-project/aztec.js/src/wallet/account_wallet.ts @@ -196,7 +196,7 @@ export class AccountWallet extends BaseWallet { } /** Returns the address of the account that implements this wallet. */ - public getAddress() { + public override getAddress() { return this.getCompleteAddress().address; } diff --git a/yarn-project/aztec/CHANGELOG.md b/yarn-project/aztec/CHANGELOG.md index ff6cdcd4bf11..054e57bc4f4b 100644 --- a/yarn-project/aztec/CHANGELOG.md +++ b/yarn-project/aztec/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## [0.35.1](https://github.com/AztecProtocol/aztec-packages/compare/aztec-package-v0.35.0...aztec-package-v0.35.1) (2024-04-16) + + +### Miscellaneous + +* **aztec-package:** Synchronize aztec-packages versions + +## [0.35.0](https://github.com/AztecProtocol/aztec-packages/compare/aztec-package-v0.34.0...aztec-package-v0.35.0) (2024-04-16) + + +### ⚠ BREAKING CHANGES + +* pay fee for account init ([#5601](https://github.com/AztecProtocol/aztec-packages/issues/5601)) + +### Features + +* Pay fee for account init ([#5601](https://github.com/AztecProtocol/aztec-packages/issues/5601)) ([aca804f](https://github.com/AztecProtocol/aztec-packages/commit/aca804f96ca9e74b6b553449333e195c0639b151)) + ## [0.34.0](https://github.com/AztecProtocol/aztec-packages/compare/aztec-package-v0.33.0...aztec-package-v0.34.0) (2024-04-10) diff --git a/yarn-project/aztec/package.json b/yarn-project/aztec/package.json index d0c984be9f3c..923d86a2938b 100644 --- a/yarn-project/aztec/package.json +++ b/yarn-project/aztec/package.json @@ -1,6 +1,6 @@ { "name": "@aztec/aztec", - "version": "0.34.0", + "version": "0.35.1", "type": "module", "exports": { ".": "./dest/index.js" diff --git a/yarn-project/circuit-types/src/interfaces/aztec-node.ts b/yarn-project/circuit-types/src/interfaces/aztec-node.ts index 918630b042eb..03e9ddbff8ab 100644 --- a/yarn-project/circuit-types/src/interfaces/aztec-node.ts +++ b/yarn-project/circuit-types/src/interfaces/aztec-node.ts @@ -7,7 +7,6 @@ import { type PUBLIC_DATA_TREE_HEIGHT, } from '@aztec/circuits.js'; import { type L1ContractAddresses } from '@aztec/ethereum'; -import { type ProcessReturnValues } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { type Fr } from '@aztec/foundation/fields'; import { type ContractClassPublic, type ContractInstanceWithAddress } from '@aztec/types/contracts'; @@ -22,7 +21,7 @@ import { } from '../logs/index.js'; import { type MerkleTreeId } from '../merkle_tree_id.js'; import { type SiblingPath } from '../sibling_path/index.js'; -import { type Tx, type TxHash, type TxReceipt } from '../tx/index.js'; +import { type ProcessReturnValues, type Tx, type TxHash, type TxReceipt } from '../tx/index.js'; import { type TxEffect } from '../tx_effect.js'; import { type SequencerConfig } from './configs.js'; import { type L2BlockNumber } from './l2_block_number.js'; @@ -283,7 +282,7 @@ export interface AztecNode { * This currently just checks that the transaction execution succeeds. * @param tx - The transaction to simulate. **/ - simulatePublicCalls(tx: Tx): Promise; + simulatePublicCalls(tx: Tx): Promise; /** * Updates the configuration of this node. diff --git a/yarn-project/circuit-types/src/keys/new_key_store.ts b/yarn-project/circuit-types/src/keys/new_key_store.ts index 10eddd49561b..8f586feb9c35 100644 --- a/yarn-project/circuit-types/src/keys/new_key_store.ts +++ b/yarn-project/circuit-types/src/keys/new_key_store.ts @@ -1,4 +1,10 @@ -import { type AztecAddress, type Fr, type PartialAddress, type PublicKey } from '@aztec/circuits.js'; +import { + type AztecAddress, + type Fr, + type GrumpkinPrivateKey, + type PartialAddress, + type PublicKey, +} from '@aztec/circuits.js'; /** * Represents a secure storage for managing keys. @@ -18,6 +24,12 @@ export interface NewKeyStore { */ addAccount(sk: Fr, partialAddress: PartialAddress): Promise; + /** + * Retrieves addresses of accounts stored in the key store. + * @returns A Promise that resolves to an array of account addresses. + */ + getAccounts(): Promise; + /** * Gets the master nullifier public key for a given account. * @throws If the account does not exist in the key store. @@ -76,4 +88,14 @@ export interface NewKeyStore { * @returns A Promise that resolves to the application outgoing viewing secret key. */ getAppOutgoingViewingSecretKey(account: AztecAddress, app: AztecAddress): Promise; + + /** + * Retrieves the master nullifier secret key (nsk_m) corresponding to the specified master nullifier public key + * (Npk_m). + * @throws If the provided public key is not associated with any of the registered accounts. + * @param masterNullifierPublicKey - The master nullifier public key to get secret key for. + * @returns A Promise that resolves to the master nullifier secret key. + * @dev Used when feeding the master nullifier secret key to the kernel circuit for nullifier keys verification. + */ + getMasterNullifierSecretKeyForPublicKey(masterNullifierPublicKey: PublicKey): Promise; } diff --git a/yarn-project/circuit-types/src/l2_block.test.ts b/yarn-project/circuit-types/src/l2_block.test.ts index 42283c1fe854..5a1a39c0699a 100644 --- a/yarn-project/circuit-types/src/l2_block.test.ts +++ b/yarn-project/circuit-types/src/l2_block.test.ts @@ -16,7 +16,7 @@ describe('L2Block', () => { // The following 2 values are copied from `testComputeKernelLogsIterationWithoutLogs` in `Decoder.t.sol` const encodedLogs = Buffer.from('0000000400000000', 'hex'); const logs = EncryptedTxL2Logs.fromBuffer(encodedLogs, true); - const referenceLogsHash = Buffer.from('006003947a07e21c81ce2062539d6d6864fe999b58b03fc46f6c190d9eac9b39', 'hex'); + const referenceLogsHash = Buffer.alloc(32); const logsHash = logs.hash(); expect(logsHash).toEqual(referenceLogsHash); @@ -27,7 +27,7 @@ describe('L2Block', () => { // The following 2 values are copied from `testComputeKernelLogs1Iteration` in `Decoder.t.sol` const encodedLogs = Buffer.from('0000000c000000080000000493e78a70', 'hex'); const logs = EncryptedTxL2Logs.fromBuffer(encodedLogs, true); - const referenceLogsHash = Buffer.from('00f458589e520e9e9bdaf746a7d226c39124e4a438f21fd41e6117a90f25f9a6', 'hex'); + const referenceLogsHash = Buffer.from('0020f9217a7218a377a78d0e8929b87d31c32d270817fe8f5fe876c61b741024', 'hex'); const logsHash = logs.hash(); expect(logsHash).toEqual(referenceLogsHash); @@ -41,7 +41,7 @@ describe('L2Block', () => { 'hex', ); const logs = EncryptedTxL2Logs.fromBuffer(encodedLogs, true); - const referenceLogsHash = Buffer.from('0084c3495a8cc56372f8f1d1efc0512920dae0f134d679cf26a12aff1509de14', 'hex'); + const referenceLogsHash = Buffer.from('007e066525b587fdfb3704301ffcfa4b6a585d95491926d0fd5698f3ae603b18', 'hex'); const logsHash = logs.hash(); expect(logsHash).toEqual(referenceLogsHash); @@ -50,12 +50,13 @@ describe('L2Block', () => { // TS equivalent of `testComputeKernelLogsMiddleIterationWithoutLogs` in `Decoder.t.sol` it('correctly computes kernel logs hash when are logs from 3 iterations (2nd iter. without logs)', () => { // The following 2 values are copied from `testComputeKernelLogsMiddleIterationWithoutLogs` in `Decoder.t.sol` + // Note: as of resolving #5017, we skip zero len logs, so we expect this and the prev hash to be the same const encodedLogs = Buffer.from( '00000028000000080000000493e78a7000000000000000140000001006a86173c86c6d3f108eefc36e7fb014', 'hex', ); const logs = EncryptedTxL2Logs.fromBuffer(encodedLogs, true); - const referenceLogsHash = Buffer.from('00fb7a99b84aad205b5a8368c12a5a6b2dc19e5d623a601717b337cdadb56aa4', 'hex'); + const referenceLogsHash = Buffer.from('007e066525b587fdfb3704301ffcfa4b6a585d95491926d0fd5698f3ae603b18', 'hex'); const logsHash = logs.hash(); expect(logsHash).toEqual(referenceLogsHash); diff --git a/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts b/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts index 4e11c696d2f3..b181aa8e6d75 100644 --- a/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts +++ b/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts @@ -1,5 +1,5 @@ import { Fr, Point } from '@aztec/circuits.js'; -import { randomBytes } from '@aztec/foundation/crypto'; +import { randomBytes, sha256Trunc } from '@aztec/foundation/crypto'; /** * Represents an individual encrypted log entry. @@ -43,6 +43,15 @@ export class EncryptedL2Log { return new EncryptedL2Log(data); } + /** + * Calculates hash of serialized logs. + * @returns Buffer containing 248 bits of information of sha256 hash. + */ + public hash(): Buffer { + const preimage = this.toBuffer(); + return sha256Trunc(preimage); + } + /** * Crates a random log. * @returns A random log. diff --git a/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts b/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts index ae10dc63ed58..3b0af9d8bf7d 100644 --- a/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts +++ b/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts @@ -5,7 +5,7 @@ function shouldBehaveLikeFunctionL2Logs( ) { describe(FunctionL2Logs.name, () => { it('can encode L2Logs to buffer and back', () => { - const l2Logs = FunctionL2Logs.random(42); + const l2Logs = FunctionL2Logs.random(3); const buffer = l2Logs.toBuffer(); const recovered = FunctionL2Logs.fromBuffer(buffer); @@ -14,7 +14,7 @@ function shouldBehaveLikeFunctionL2Logs( }); it('can encode L2Logs to JSON and back', () => { - const l2Logs = FunctionL2Logs.random(42); + const l2Logs = FunctionL2Logs.random(3); const buffer = l2Logs.toJSON(); const recovered = FunctionL2Logs.fromJSON(buffer); @@ -23,7 +23,7 @@ function shouldBehaveLikeFunctionL2Logs( }); it('getSerializedLength returns the correct length', () => { - const l2Logs = FunctionL2Logs.random(42); + const l2Logs = FunctionL2Logs.random(3); const buffer = l2Logs.toBuffer(); const recovered = FunctionL2Logs.fromBuffer(buffer); diff --git a/yarn-project/circuit-types/src/logs/function_l2_logs.ts b/yarn-project/circuit-types/src/logs/function_l2_logs.ts index 12c44942915f..dd8650132d5c 100644 --- a/yarn-project/circuit-types/src/logs/function_l2_logs.ts +++ b/yarn-project/circuit-types/src/logs/function_l2_logs.ts @@ -1,5 +1,6 @@ -import { sha256 } from '@aztec/foundation/crypto'; -import { BufferReader, prefixBufferWithLength, truncateAndPad } from '@aztec/foundation/serialize'; +import { MAX_ENCRYPTED_LOGS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL } from '@aztec/circuits.js'; +import { sha256Trunc } from '@aztec/foundation/crypto'; +import { BufferReader, prefixBufferWithLength } from '@aztec/foundation/serialize'; import { EncryptedL2Log } from './encrypted_l2_log.js'; import { UnencryptedL2Log } from './unencrypted_l2_log.js'; @@ -38,12 +39,13 @@ export abstract class FunctionL2Logs l.hash())); + return sha256Trunc(preimage); } /** @@ -85,10 +87,12 @@ export class EncryptedFunctionL2Logs extends FunctionL2Logs { /** * Creates a new L2Logs object with `numLogs` logs. * @param numLogs - The number of logs to create. - * @param logType - The type of logs to generate. * @returns A new EncryptedFunctionL2Logs object. */ public static random(numLogs: number): EncryptedFunctionL2Logs { + if (numLogs > MAX_ENCRYPTED_LOGS_PER_CALL) { + throw new Error(`Trying to create ${numLogs} logs for one call (max: ${MAX_ENCRYPTED_LOGS_PER_CALL})`); + } const logs: EncryptedL2Log[] = []; for (let i = 0; i < numLogs; i++) { logs.push(EncryptedL2Log.random()); @@ -135,10 +139,12 @@ export class UnencryptedFunctionL2Logs extends FunctionL2Logs /** * Creates a new L2Logs object with `numLogs` logs. * @param numLogs - The number of logs to create. - * @param logType - The type of logs to generate. * @returns A new UnencryptedFunctionL2Logs object. */ public static random(numLogs: number): UnencryptedFunctionL2Logs { + if (numLogs > MAX_UNENCRYPTED_LOGS_PER_CALL) { + throw new Error(`Trying to create ${numLogs} logs for one call (max: ${MAX_UNENCRYPTED_LOGS_PER_CALL})`); + } const logs: UnencryptedL2Log[] = []; for (let i = 0; i < numLogs; i++) { logs.push(UnencryptedL2Log.random()); diff --git a/yarn-project/circuit-types/src/logs/l1_note_payload/note.ts b/yarn-project/circuit-types/src/logs/l1_note_payload/note.ts index 9a56b9047781..9562a277e488 100644 --- a/yarn-project/circuit-types/src/logs/l1_note_payload/note.ts +++ b/yarn-project/circuit-types/src/logs/l1_note_payload/note.ts @@ -39,7 +39,7 @@ export class Note extends Vector { * Returns a hex representation of the note. * @returns A hex string with the vector length as first element. */ - toString() { + override toString() { return '0x' + this.toBuffer().toString('hex'); } diff --git a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts index 843de7951968..6b0227c43348 100644 --- a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts +++ b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts @@ -3,7 +3,7 @@ import { EncryptedL2BlockL2Logs, UnencryptedL2BlockL2Logs } from './l2_block_l2_ function shouldBehaveLikeL2BlockL2Logs(L2BlockL2Logs: typeof EncryptedL2BlockL2Logs | typeof UnencryptedL2BlockL2Logs) { describe(L2BlockL2Logs.name, () => { it('can encode L2Logs to buffer and back', () => { - const l2Logs = L2BlockL2Logs.random(3, 6, 2); + const l2Logs = L2BlockL2Logs.random(3, 4, 2); const buffer = l2Logs.toBuffer(); const recovered = L2BlockL2Logs.fromBuffer(buffer); @@ -12,7 +12,7 @@ function shouldBehaveLikeL2BlockL2Logs(L2BlockL2Logs: typeof EncryptedL2BlockL2L }); it('getSerializedLength returns the correct length', () => { - const l2Logs = L2BlockL2Logs.random(3, 6, 2); + const l2Logs = L2BlockL2Logs.random(3, 4, 2); const buffer = l2Logs.toBuffer(); const recovered = L2BlockL2Logs.fromBuffer(buffer); @@ -21,7 +21,7 @@ function shouldBehaveLikeL2BlockL2Logs(L2BlockL2Logs: typeof EncryptedL2BlockL2L }); it('serializes to and from JSON', () => { - const l2Logs = L2BlockL2Logs.random(3, 6, 2); + const l2Logs = L2BlockL2Logs.random(3, 4, 2); const json = l2Logs.toJSON(); const recovered = L2BlockL2Logs.fromJSON(json); expect(recovered).toEqual(l2Logs); diff --git a/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts b/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts index 6f706a4c72bc..6be5194aa49a 100644 --- a/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts +++ b/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts @@ -3,7 +3,7 @@ import { EncryptedTxL2Logs, UnencryptedTxL2Logs } from './tx_l2_logs.js'; function shouldBehaveLikeTxL2Logs(TxL2Logs: typeof EncryptedTxL2Logs | typeof UnencryptedTxL2Logs) { describe(TxL2Logs.name, () => { it('can encode TxL2Logs to buffer and back', () => { - const l2Logs = TxL2Logs.random(6, 2); + const l2Logs = TxL2Logs.random(4, 2); const buffer = l2Logs.toBuffer(); const recovered = TxL2Logs.fromBuffer(buffer); @@ -12,7 +12,7 @@ function shouldBehaveLikeTxL2Logs(TxL2Logs: typeof EncryptedTxL2Logs | typeof Un }); it('can encode TxL2Logs to JSON and back', () => { - const l2Logs = TxL2Logs.random(6, 2); + const l2Logs = TxL2Logs.random(4, 2); const buffer = l2Logs.toJSON(); const recovered = TxL2Logs.fromJSON(buffer); @@ -21,7 +21,7 @@ function shouldBehaveLikeTxL2Logs(TxL2Logs: typeof EncryptedTxL2Logs | typeof Un }); it('getSerializedLength returns the correct length', () => { - const l2Logs = TxL2Logs.random(6, 2); + const l2Logs = TxL2Logs.random(4, 2); const buffer = l2Logs.toBuffer(); const recovered = TxL2Logs.fromBuffer(buffer); diff --git a/yarn-project/circuit-types/src/logs/tx_l2_logs.ts b/yarn-project/circuit-types/src/logs/tx_l2_logs.ts index bd6fe976ed02..e0814eafa4e5 100644 --- a/yarn-project/circuit-types/src/logs/tx_l2_logs.ts +++ b/yarn-project/circuit-types/src/logs/tx_l2_logs.ts @@ -1,5 +1,6 @@ -import { sha256 } from '@aztec/foundation/crypto'; -import { BufferReader, prefixBufferWithLength, truncateAndPad } from '@aztec/foundation/serialize'; +import { MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX } from '@aztec/circuits.js'; +import { sha256Trunc } from '@aztec/foundation/crypto'; +import { BufferReader, prefixBufferWithLength } from '@aztec/foundation/serialize'; import isEqual from 'lodash.isequal'; @@ -86,12 +87,12 @@ export abstract class TxL2Logs { const logsHashes: [Buffer, Buffer] = [Buffer.alloc(32), Buffer.alloc(32)]; let kernelPublicInputsLogsHash = Buffer.alloc(32); - for (const logsFromSingleFunctionCall of this.functionLogs) { + for (const logsFromSingleFunctionCall of this.unrollLogs()) { logsHashes[0] = kernelPublicInputsLogsHash; logsHashes[1] = logsFromSingleFunctionCall.hash(); // privateCircuitPublicInputsLogsHash // Hash logs hash from the public inputs of previous kernel iteration and logs hash from private circuit public inputs - kernelPublicInputsLogsHash = truncateAndPad(sha256(Buffer.concat(logsHashes))); + kernelPublicInputsLogsHash = sha256Trunc(Buffer.concat(logsHashes)); } return kernelPublicInputsLogsHash; @@ -129,6 +130,11 @@ export class UnencryptedTxL2Logs extends TxL2Logs { * @returns A new `TxL2Logs` object. */ public static random(numCalls: number, numLogsPerCall: number): UnencryptedTxL2Logs { + if (numCalls * numLogsPerCall > MAX_UNENCRYPTED_LOGS_PER_TX) { + throw new Error( + `Trying to create ${numCalls * numLogsPerCall} logs for one tx (max: ${MAX_UNENCRYPTED_LOGS_PER_TX})`, + ); + } const functionLogs: UnencryptedFunctionL2Logs[] = []; for (let i = 0; i < numCalls; i++) { functionLogs.push(UnencryptedFunctionL2Logs.random(numLogsPerCall)); @@ -178,6 +184,11 @@ export class EncryptedTxL2Logs extends TxL2Logs { * @returns A new `TxL2Logs` object. */ public static random(numCalls: number, numLogsPerCall: number): EncryptedTxL2Logs { + if (numCalls * numLogsPerCall > MAX_ENCRYPTED_LOGS_PER_TX) { + throw new Error( + `Trying to create ${numCalls * numLogsPerCall} logs for one tx (max: ${MAX_ENCRYPTED_LOGS_PER_TX})`, + ); + } const functionLogs: EncryptedFunctionL2Logs[] = []; for (let i = 0; i < numCalls; i++) { functionLogs.push(EncryptedFunctionL2Logs.random(numLogsPerCall)); diff --git a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts index a8bc9ee0fecc..40d7e598cf59 100644 --- a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts +++ b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts @@ -1,6 +1,6 @@ import { AztecAddress } from '@aztec/circuits.js'; import { EventSelector } from '@aztec/foundation/abi'; -import { randomBytes } from '@aztec/foundation/crypto'; +import { randomBytes, sha256Trunc } from '@aztec/foundation/crypto'; import { BufferReader, prefixBufferWithLength } from '@aztec/foundation/serialize'; /** @@ -82,6 +82,15 @@ export class UnencryptedL2Log { return new UnencryptedL2Log(contractAddress, selector, data); } + /** + * Calculates hash of serialized logs. + * @returns Buffer containing 248 bits of information of sha256 hash. + */ + public hash(): Buffer { + const preimage = this.toBuffer(); + return sha256Trunc(preimage); + } + /** * Crates a random log. * @returns A random log. diff --git a/yarn-project/circuit-types/src/mocks.ts b/yarn-project/circuit-types/src/mocks.ts index 3f6c48c134f3..3c613163756d 100644 --- a/yarn-project/circuit-types/src/mocks.ts +++ b/yarn-project/circuit-types/src/mocks.ts @@ -1,16 +1,19 @@ import { AztecAddress, CallRequest, + GasSettings, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, PartialPrivateTailPublicInputsForPublic, PrivateKernelTailCircuitPublicInputs, Proof, + type PublicCallRequest, + SideEffect, SideEffectLinkedToNoteHash, computeContractClassId, getContractClassFromArtifact, } from '@aztec/circuits.js'; import { makePublicCallRequest } from '@aztec/circuits.js/testing'; -import { type ContractArtifact, type DecodedReturn } from '@aztec/foundation/abi'; +import { type ContractArtifact } from '@aztec/foundation/abi'; import { makeTuple } from '@aztec/foundation/array'; import { times } from '@aztec/foundation/collection'; import { randomBytes } from '@aztec/foundation/crypto'; @@ -20,7 +23,7 @@ import { type ContractInstanceWithAddress, SerializableContractInstance } from ' import { EncryptedL2Log } from './logs/encrypted_l2_log.js'; import { EncryptedFunctionL2Logs, EncryptedTxL2Logs, Note, UnencryptedTxL2Logs } from './logs/index.js'; import { ExtendedNote } from './notes/index.js'; -import { SimulatedTx, Tx, TxHash } from './tx/index.js'; +import { type ProcessReturnValues, SimulatedTx, Tx, TxHash } from './tx/index.js'; /** * Testing utility to create empty logs composed from a single empty log. @@ -38,18 +41,28 @@ export const mockTx = ( hasLogs = false, numberOfNonRevertiblePublicCallRequests = MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX / 2, numberOfRevertiblePublicCallRequests = MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX / 2, + publicCallRequests = [], }: { hasLogs?: boolean; numberOfNonRevertiblePublicCallRequests?: number; numberOfRevertiblePublicCallRequests?: number; + publicCallRequests?: PublicCallRequest[]; } = {}, ) => { - const totalPublicCallRequests = numberOfNonRevertiblePublicCallRequests + numberOfRevertiblePublicCallRequests; - const publicCallRequests = times(totalPublicCallRequests, i => makePublicCallRequest(seed + 0x100 + i)); + const totalPublicCallRequests = + numberOfNonRevertiblePublicCallRequests + numberOfRevertiblePublicCallRequests || publicCallRequests.length; + if (publicCallRequests.length && publicCallRequests.length !== totalPublicCallRequests) { + throw new Error( + `Provided publicCallRequests does not match the required number of call requests. Expected ${totalPublicCallRequests}. Got ${publicCallRequests.length}`, + ); + } const isForPublic = totalPublicCallRequests > 0; const data = PrivateKernelTailCircuitPublicInputs.empty(); const firstNullifier = new SideEffectLinkedToNoteHash(new Fr(seed + 1), new Fr(seed + 2), Fr.ZERO); + const encryptedLogs = hasLogs ? EncryptedTxL2Logs.random(2, 3) : EncryptedTxL2Logs.empty(); // 2 priv function invocations creating 3 encrypted logs each + const unencryptedLogs = hasLogs ? UnencryptedTxL2Logs.random(2, 1) : UnencryptedTxL2Logs.empty(); // 2 priv function invocations creating 1 unencrypted log each + data.constants.gasSettings = GasSettings.default(); if (isForPublic) { data.forRollup = undefined; @@ -57,29 +70,37 @@ export const mockTx = ( data.forPublic.endNonRevertibleData.newNullifiers[0] = firstNullifier; - data.forPublic.end.publicCallStack = makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, i => - i < numberOfRevertiblePublicCallRequests ? publicCallRequests[i].toCallRequest() : CallRequest.empty(), - ); + publicCallRequests = publicCallRequests.length + ? publicCallRequests.slice().sort((a, b) => b.callContext.sideEffectCounter - a.callContext.sideEffectCounter) + : times(totalPublicCallRequests, i => makePublicCallRequest(seed + 0x100 + i)); data.forPublic.endNonRevertibleData.publicCallStack = makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, i => i < numberOfNonRevertiblePublicCallRequests - ? publicCallRequests[i + numberOfRevertiblePublicCallRequests].toCallRequest() + ? publicCallRequests[numberOfRevertiblePublicCallRequests + i].toCallRequest() : CallRequest.empty(), ); - } else { - data.forRollup!.end.newNullifiers[0] = firstNullifier.value; - } - - const target = isForPublic ? data.forPublic! : data.forRollup!; + if (hasLogs) { + let i = 1; // 0 used in first nullifier + encryptedLogs.functionLogs.forEach((log, j) => { + // ts complains if we dont check .forPublic here, even though it is defined ^ + if (data.forPublic) { + data.forPublic.end.encryptedLogsHashes[j] = new SideEffect(Fr.fromBuffer(log.hash()), new Fr(i++)); + } + }); + unencryptedLogs.functionLogs.forEach((log, j) => { + if (data.forPublic) { + data.forPublic.end.unencryptedLogsHashes[j] = new SideEffect(Fr.fromBuffer(log.hash()), new Fr(i++)); + } + }); + } - const encryptedLogs = hasLogs ? EncryptedTxL2Logs.random(8, 3) : EncryptedTxL2Logs.empty(); // 8 priv function invocations creating 3 encrypted logs each - const unencryptedLogs = hasLogs ? UnencryptedTxL2Logs.random(11, 2) : UnencryptedTxL2Logs.empty(); // 8 priv function invocations creating 3 encrypted logs each - if (!hasLogs) { - target.end.encryptedLogsHash = Fr.ZERO; - target.end.unencryptedLogsHash = Fr.ZERO; + data.forPublic.end.publicCallStack = makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, i => + i < numberOfRevertiblePublicCallRequests ? publicCallRequests[i].toCallRequest() : CallRequest.empty(), + ); } else { - target.end.encryptedLogsHash = Fr.fromBuffer(encryptedLogs.hash()); - target.end.unencryptedLogsHash = Fr.fromBuffer(unencryptedLogs.hash()); + data.forRollup!.end.newNullifiers[0] = firstNullifier.value; + data.forRollup!.end.encryptedLogsHash = hasLogs ? Fr.fromBuffer(encryptedLogs.hash()) : Fr.ZERO; + data.forRollup!.end.unencryptedLogsHash = hasLogs ? Fr.fromBuffer(unencryptedLogs.hash()) : Fr.ZERO; } const tx = new Tx(data, new Proof(Buffer.alloc(0)), encryptedLogs, unencryptedLogs, publicCallRequests); @@ -92,7 +113,7 @@ export const mockTxForRollup = (seed = 1, { hasLogs = false }: { hasLogs?: boole export const mockSimulatedTx = (seed = 1, hasLogs = true) => { const tx = mockTx(seed, { hasLogs }); - const dec: DecodedReturn = [1n, 2n, 3n, 4n]; + const dec: ProcessReturnValues = [new Fr(1n), new Fr(2n), new Fr(3n), new Fr(4n)]; return new SimulatedTx(tx, dec, dec); }; diff --git a/yarn-project/circuit-types/src/simulation_error.ts b/yarn-project/circuit-types/src/simulation_error.ts index 69e1b98166f3..aa0ccd1dfa6e 100644 --- a/yarn-project/circuit-types/src/simulation_error.ts +++ b/yarn-project/circuit-types/src/simulation_error.ts @@ -72,6 +72,8 @@ export class SimulationError extends Error { options?: ErrorOptions, ) { super(originalMessage, options); + const getMessage = () => this.getMessage(); + const getStack = () => this.getStack(); Object.defineProperties(this, { message: { configurable: false, @@ -82,7 +84,7 @@ export class SimulationError extends Error { * @returns The message. */ get() { - return this.getMessage(); + return getMessage(); }, }, stack: { @@ -93,7 +95,7 @@ export class SimulationError extends Error { * @returns The stack. */ get() { - return this.getStack(); + return getStack(); }, }, }); diff --git a/yarn-project/circuit-types/src/tx/simulated_tx.test.ts b/yarn-project/circuit-types/src/tx/simulated_tx.test.ts index 29cc00194779..167c91259fa8 100644 --- a/yarn-project/circuit-types/src/tx/simulated_tx.test.ts +++ b/yarn-project/circuit-types/src/tx/simulated_tx.test.ts @@ -6,4 +6,11 @@ describe('simulated_tx', () => { const simulatedTx = mockSimulatedTx(); expect(SimulatedTx.fromJSON(simulatedTx.toJSON())).toEqual(simulatedTx); }); + + it('convert undefined effects to and from json', () => { + const simulatedTx = mockSimulatedTx(); + simulatedTx.privateReturnValues = undefined; + simulatedTx.publicReturnValues = undefined; + expect(SimulatedTx.fromJSON(simulatedTx.toJSON())).toEqual(simulatedTx); + }); }); diff --git a/yarn-project/circuit-types/src/tx/simulated_tx.ts b/yarn-project/circuit-types/src/tx/simulated_tx.ts index febf33cdfb45..baef7a2d4ea6 100644 --- a/yarn-project/circuit-types/src/tx/simulated_tx.ts +++ b/yarn-project/circuit-types/src/tx/simulated_tx.ts @@ -1,8 +1,9 @@ -import { AztecAddress } from '@aztec/circuits.js'; -import { type ProcessReturnValues } from '@aztec/foundation/abi'; +import { Fr } from '@aztec/circuits.js'; import { Tx } from './tx.js'; +export type ProcessReturnValues = Fr[] | undefined; + export class SimulatedTx { constructor( public tx: Tx, @@ -15,17 +16,11 @@ export class SimulatedTx { * @returns A plain object with SimulatedTx properties. */ public toJSON() { - const returnToJson = (data: ProcessReturnValues): string => { - const replacer = (key: string, value: any): any => { - if (typeof value === 'bigint') { - return value.toString() + 'n'; // Indicate bigint with "n" - } else if (value instanceof AztecAddress) { - return value.toString(); - } else { - return value; - } - }; - return JSON.stringify(data, replacer); + const returnToJson = (data: ProcessReturnValues | undefined): string => { + if (data === undefined) { + return JSON.stringify(data); + } + return JSON.stringify(data.map(fr => fr.toString())); }; return { @@ -41,22 +36,11 @@ export class SimulatedTx { * @returns A Tx class object. */ public static fromJSON(obj: any) { - const returnFromJson = (json: string): ProcessReturnValues => { - if (json == undefined) { + const returnFromJson = (json: string): ProcessReturnValues | undefined => { + if (json === undefined) { return json; } - const reviver = (key: string, value: any): any => { - if (typeof value === 'string') { - if (value.match(/\d+n$/)) { - // Detect bigint serialization - return BigInt(value.slice(0, -1)); - } else if (value.match(/^0x[a-fA-F0-9]{64}$/)) { - return AztecAddress.fromString(value); - } - } - return value; - }; - return JSON.parse(json, reviver); + return JSON.parse(json).map(Fr.fromString); }; const tx = Tx.fromJSON(obj.tx); diff --git a/yarn-project/circuit-types/src/tx/tx.ts b/yarn-project/circuit-types/src/tx/tx.ts index 02d4273ab6a9..1bf14f809be8 100644 --- a/yarn-project/circuit-types/src/tx/tx.ts +++ b/yarn-project/circuit-types/src/tx/tx.ts @@ -40,6 +40,8 @@ export class Tx { public readonly enqueuedPublicFunctionCalls: PublicCallRequest[], ) { if (this.unencryptedLogs.functionLogs.length < this.encryptedLogs.functionLogs.length) { + // TODO(Miranda): This error was not throwing in some cases, as logs are nested objects which would show len 1 even if no logs existed + // Many tests produce enc logs and no unenc logs, so this error should have been throwing even in good cases // This check is present because each private function invocation creates encrypted FunctionL2Logs object and // both public and private function invocations create unencrypted FunctionL2Logs object. Hence "num unencrypted" // >= "num encrypted". diff --git a/yarn-project/circuit-types/src/tx_execution_request.ts b/yarn-project/circuit-types/src/tx_execution_request.ts index eba0eda27d87..9169dfe0ceea 100644 --- a/yarn-project/circuit-types/src/tx_execution_request.ts +++ b/yarn-project/circuit-types/src/tx_execution_request.ts @@ -1,4 +1,4 @@ -import { AztecAddress, Fr, FunctionData, TxContext, TxRequest, Vector } from '@aztec/circuits.js'; +import { AztecAddress, Fr, FunctionData, GasSettings, TxContext, TxRequest, Vector } from '@aztec/circuits.js'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { type FieldsOf } from '@aztec/foundation/types'; @@ -38,10 +38,13 @@ export class TxExecutionRequest { * These witnesses are not expected to be stored in the local witnesses database of the PXE. */ public authWitnesses: AuthWitness[], + + /** Gas choices for this transaction. */ + public gasSettings: GasSettings, ) {} toTxRequest(): TxRequest { - return new TxRequest(this.origin, this.functionData, this.argsHash, this.txContext); + return new TxRequest(this.origin, this.functionData, this.argsHash, this.txContext, this.gasSettings); } static getFields(fields: FieldsOf) { @@ -52,6 +55,7 @@ export class TxExecutionRequest { fields.txContext, fields.packedArguments, fields.authWitnesses, + fields.gasSettings, ] as const; } @@ -71,6 +75,7 @@ export class TxExecutionRequest { this.txContext, new Vector(this.packedArguments), new Vector(this.authWitnesses), + this.gasSettings, ); } @@ -96,6 +101,7 @@ export class TxExecutionRequest { reader.readObject(TxContext), reader.readVector(PackedValues), reader.readVector(AuthWitness), + reader.readObject(GasSettings), ); } diff --git a/yarn-project/circuits.js/package.json b/yarn-project/circuits.js/package.json index 1c375c3b714b..ecb0883e9208 100644 --- a/yarn-project/circuits.js/package.json +++ b/yarn-project/circuits.js/package.json @@ -11,6 +11,7 @@ "./hash": "./dest/hash/index.js", "./barretenberg": "./dest/barretenberg/index.js", "./testing": "./dest/tests/index.js", + "./testing/fixtures": "./dest/tests/fixtures.js", "./interfaces": "./dest/interfaces/index.js", "./utils": "./dest/utils/index.js", "./types": "./dest/types/index.js", diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 253c792aab92..6441113ed89e 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -12,6 +12,8 @@ export const MAX_NOTE_HASH_READ_REQUESTS_PER_CALL = 32; export const MAX_NULLIFIER_READ_REQUESTS_PER_CALL = 2; export const MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL = 2; export const MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; +export const MAX_ENCRYPTED_LOGS_PER_CALL = 4; +export const MAX_UNENCRYPTED_LOGS_PER_CALL = 4; export const MAX_NEW_NOTE_HASHES_PER_TX = 64; export const MAX_NEW_NULLIFIERS_PER_TX = 64; export const MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX = 8; @@ -23,8 +25,11 @@ export const MAX_NOTE_HASH_READ_REQUESTS_PER_TX = 128; export const MAX_NULLIFIER_READ_REQUESTS_PER_TX = 8; export const MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX = 8; export const MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX = 4; +export const MAX_ENCRYPTED_LOGS_PER_TX = 8; +export const MAX_UNENCRYPTED_LOGS_PER_TX = 8; export const NUM_ENCRYPTED_LOGS_HASHES_PER_TX = 1; export const NUM_UNENCRYPTED_LOGS_HASHES_PER_TX = 1; +export const MAX_PUBLIC_DATA_HINTS = 64; export const NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP = 16; export const VK_TREE_HEIGHT = 3; export const FUNCTION_TREE_HEIGHT = 5; @@ -51,11 +56,12 @@ export const L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH = 12; export const FUNCTION_SELECTOR_NUM_BYTES = 4; export const ARGS_HASH_CHUNK_LENGTH = 64; export const ARGS_HASH_CHUNK_COUNT = 64; +export const MAX_ARGS_LENGTH = ARGS_HASH_CHUNK_COUNT * ARGS_HASH_CHUNK_LENGTH; export const INITIALIZATION_SLOT_SEPARATOR = 1000_000_000; export const INITIAL_L2_BLOCK_NUM = 1; -export const BLOB_SIZE_IN_BYTES = 126976; +export const BLOB_SIZE_IN_BYTES = 31 * 4096; export const NESTED_CALL_L2_GAS_BUFFER = 20000; -export const MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 16000; +export const MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS = 16200; export const MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS = 3000; export const MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS = 3000; export const REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS = 19; @@ -68,18 +74,13 @@ export const REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE = 0xe7af816635466f128568edb04c9fa024f6c87fb9010fdbffa68b3d99n; export const DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE = 0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631n; -export const DEPLOYER_CONTRACT_ADDRESS = 0x1df42e0457430b8d294d920181cc72ae0e3c5f8afd8d62d461bd26773cfdf3c1n; -export const L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH = 17; -export const MAX_NOTE_FIELDS_LENGTH = 20; -export const GET_NOTE_ORACLE_RETURN_LENGTH = 23; -export const MAX_NOTES_PER_PAGE = 10; -export const VIEW_NOTE_ORACLE_RETURN_LENGTH = 212; +export const DEPLOYER_CONTRACT_ADDRESS = 0x1b5ecf3d26907648cf737f4304759b8c5850478e839e72f8ce1f5791b286e8f2n; export const AZTEC_ADDRESS_LENGTH = 1; -export const CALL_CONTEXT_LENGTH = 18; -export const GAS_SETTINGS_LENGTH = 10; export const DIMENSION_GAS_SETTINGS_LENGTH = 3; export const GAS_FEES_LENGTH = 3; -export const GAS_USED_LENGTH = 3; +export const GAS_LENGTH = 3; +export const GAS_SETTINGS_LENGTH = 1 + 3 * DIMENSION_GAS_SETTINGS_LENGTH; +export const CALL_CONTEXT_LENGTH = 8 + GAS_SETTINGS_LENGTH + GAS_LENGTH; export const CONTENT_COMMITMENT_LENGTH = 4; export const CONTRACT_INSTANCE_LENGTH = 6; export const CONTRACT_STORAGE_READ_LENGTH = 2; @@ -87,21 +88,61 @@ export const CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH = 2; export const ETH_ADDRESS_LENGTH = 1; export const FUNCTION_DATA_LENGTH = 2; export const FUNCTION_LEAF_PREIMAGE_LENGTH = 5; -export const GLOBAL_VARIABLES_LENGTH = 9; -export const HEADER_LENGTH = 23; +export const GLOBAL_VARIABLES_LENGTH = 6 + GAS_FEES_LENGTH; +export const APPEND_ONLY_TREE_SNAPSHOT_LENGTH = 2; export const L1_TO_L2_MESSAGE_LENGTH = 6; export const L2_TO_L1_MESSAGE_LENGTH = 2; export const MAX_BLOCK_NUMBER_LENGTH = 2; export const NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH = 4; export const NULLIFIER_KEY_VALIDATION_REQUEST_CONTEXT_LENGTH = 5; export const PARTIAL_STATE_REFERENCE_LENGTH = 6; -export const PRIVATE_CALL_STACK_ITEM_LENGTH = 221; -export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 218; -export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 209; -export const STATE_REFERENCE_LENGTH = 8; +export const READ_REQUEST_LENGTH = 2; +export const SIDE_EFFECT_LENGTH = 2; +export const SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH = 3; +export const STATE_REFERENCE_LENGTH = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; export const TX_CONTEXT_DATA_LENGTH = 4; -export const TX_REQUEST_LENGTH = 8; -export const ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH = 22; +export const TX_REQUEST_LENGTH = 2 + TX_CONTEXT_DATA_LENGTH + FUNCTION_DATA_LENGTH + GAS_SETTINGS_LENGTH; +export const HEADER_LENGTH = + APPEND_ONLY_TREE_SNAPSHOT_LENGTH + CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH; +export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = + CALL_CONTEXT_LENGTH + + 3 + + MAX_BLOCK_NUMBER_LENGTH + + SIDE_EFFECT_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL + + READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL + + NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH * MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL + + SIDE_EFFECT_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL + + SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL + + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + + L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL + + 2 + + SIDE_EFFECT_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL + + SIDE_EFFECT_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL + + 2 + + HEADER_LENGTH + + 2; +export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = + CALL_CONTEXT_LENGTH + + 2 + + READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL + + READ_REQUEST_LENGTH * MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL + + CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL + + CONTRACT_STORAGE_READ_LENGTH * MAX_PUBLIC_DATA_READS_PER_CALL + + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + + SIDE_EFFECT_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL + + SIDE_EFFECT_LINKED_TO_NOTE_HASH_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL + + L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL + + 2 + + SIDE_EFFECT_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL + + 1 + + HEADER_LENGTH + + AZTEC_ADDRESS_LENGTH + + /* revert_code */ 1 + + GAS_LENGTH; +export const PRIVATE_CALL_STACK_ITEM_LENGTH = + AZTEC_ADDRESS_LENGTH + FUNCTION_DATA_LENGTH + PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH; +export const ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH = 2 + FUNCTION_DATA_LENGTH + CALL_CONTEXT_LENGTH; export const GET_NOTES_ORACLE_RETURN_LENGTH = 674; export const NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 2048; export const NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048; diff --git a/yarn-project/circuits.js/src/contract/contract_address.ts b/yarn-project/circuits.js/src/contract/contract_address.ts index 96196f019719..695ef983a543 100644 --- a/yarn-project/circuits.js/src/contract/contract_address.ts +++ b/yarn-project/circuits.js/src/contract/contract_address.ts @@ -11,7 +11,7 @@ import { type PublicKey } from '../types/public_key.js'; // TODO(@spalladino): Review all generator indices in this file /** - * Returns the deployment address for a given contract instance as defined on the [Yellow Paper](../../../../yellow-paper/docs/addresses-and-keys/specification.md). + * Returns the deployment address for a given contract instance as defined on the [Protocol Specs](../../../../docs/docs/protocol-specs/addresses-and-keys/specification.md). * ``` * salted_initialization_hash = pedersen([salt, initialization_hash, deployer, portal_contract_address as Field], GENERATOR__SALTED_INITIALIZATION_HASH) * partial_address = pedersen([contract_class_id, salted_initialization_hash], GENERATOR__CONTRACT_PARTIAL_ADDRESS_V1) diff --git a/yarn-project/circuits.js/src/contract/private_function_membership_proof.ts b/yarn-project/circuits.js/src/contract/private_function_membership_proof.ts index cbd39f5f2530..2857b463c24e 100644 --- a/yarn-project/circuits.js/src/contract/private_function_membership_proof.ts +++ b/yarn-project/circuits.js/src/contract/private_function_membership_proof.ts @@ -82,7 +82,7 @@ export function createPrivateFunctionMembershipProof( /** * Verifies that a private function with a membership proof as emitted by the ClassRegisterer contract is valid, - * as defined in the yellow paper at contract-deployment/classes: + * as defined in the protocol specs at contract-deployment/classes: * * ``` * // Load contract class from local db diff --git a/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts index 6df7afdb72e2..a6b368c6d5e2 100644 --- a/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts +++ b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts @@ -66,7 +66,7 @@ export function createUnconstrainedFunctionMembershipProof( /** * Verifies that an unconstrained function with a membership proof as emitted by the ClassRegisterer contract is valid, - * as defined in the yellow paper at contract-deployment/classes: + * as defined in the protocol specs at contract-deployment/classes: * * ``` * // Load contract class from local db diff --git a/yarn-project/circuits.js/src/hints/build_hints.test.ts b/yarn-project/circuits.js/src/hints/build_hints.test.ts index 7ac9ee39a521..5df210ca1e87 100644 --- a/yarn-project/circuits.js/src/hints/build_hints.test.ts +++ b/yarn-project/circuits.js/src/hints/build_hints.test.ts @@ -22,10 +22,8 @@ import { buildNullifierNonExistentReadRequestHints, buildNullifierReadRequestHin describe('buildNullifierReadRequestHints', () => { const contractAddress = AztecAddress.random(); const settledNullifierInnerValue = 99999; - const settledNullifierValue = makeNullifier(settledNullifierInnerValue).value; const oracle = { - getNullifierMembershipWitness: (value: Fr) => - value.equals(settledNullifierValue) ? ({ membershipWitness: {}, leafPreimage: {} } as any) : undefined, + getNullifierMembershipWitness: () => ({ membershipWitness: {}, leafPreimage: {} } as any), }; let nullifierReadRequests: Tuple; let nullifiers: Tuple; @@ -113,11 +111,6 @@ describe('buildNullifierReadRequestHints', () => { const hints = await buildHints(); expect(hints).toEqual(expectedHints); }); - - it('throws if reading an unknown nullifier', async () => { - nullifierReadRequests[0] = makeReadRequest(88888); - await expect(buildHints()).rejects.toThrow('Read request is reading an unknown nullifier value.'); - }); }); describe('buildNullifierNonExistentReadRequestHints', () => { diff --git a/yarn-project/circuits.js/src/hints/build_hints.ts b/yarn-project/circuits.js/src/hints/build_hints.ts index 1266082c2d06..302ed3a14f9d 100644 --- a/yarn-project/circuits.js/src/hints/build_hints.ts +++ b/yarn-project/circuits.js/src/hints/build_hints.ts @@ -17,14 +17,14 @@ import { NullifierReadRequestHintsBuilder } from '../structs/read_request_hints. import { SideEffectLinkedToNoteHash } from '../structs/side_effects.js'; import { countAccumulatedItems } from '../utils/index.js'; -export interface NullifierMembershipWitnessWithPreimage { +interface NullifierMembershipWitnessWithPreimage { membershipWitness: MembershipWitness; leafPreimage: IndexedTreeLeafPreimage; } export async function buildNullifierReadRequestHints( oracle: { - getNullifierMembershipWitness(nullifier: Fr): Promise; + getNullifierMembershipWitness(nullifier: Fr): Promise; }, nullifierReadRequests: Tuple, nullifiers: Tuple, @@ -46,10 +46,6 @@ export async function buildNullifierReadRequestHints( builder.addPendingReadRequest(i, pendingValueIndex); } else { const membershipWitnessWithPreimage = await oracle.getNullifierMembershipWitness(value); - if (!membershipWitnessWithPreimage) { - throw new Error('Read request is reading an unknown nullifier value.'); - } - builder.addSettledReadRequest( i, membershipWitnessWithPreimage.membershipWitness, diff --git a/yarn-project/circuits.js/src/hints/build_public_data_hints.test.ts b/yarn-project/circuits.js/src/hints/build_public_data_hints.test.ts new file mode 100644 index 000000000000..a041d8fd32f8 --- /dev/null +++ b/yarn-project/circuits.js/src/hints/build_public_data_hints.test.ts @@ -0,0 +1,123 @@ +import { makeTuple } from '@aztec/foundation/array'; +import { Fr } from '@aztec/foundation/fields'; +import { type Tuple } from '@aztec/foundation/serialize'; + +import { + MAX_PUBLIC_DATA_HINTS, + MAX_PUBLIC_DATA_READS_PER_TX, + type MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, +} from '../constants.gen.js'; +import { PublicDataRead, PublicDataTreeLeafPreimage, PublicDataUpdateRequest } from '../structs/index.js'; +import { buildPublicDataHints } from './build_public_data_hints.js'; + +class ExpectedHint { + constructor(public leafSlot: number, public value: number, public matchOrLowLeafSlot: number) {} + + static empty() { + return new ExpectedHint(0, 0, 0); + } + + toExpectedObject() { + return expect.objectContaining({ + leafSlot: new Fr(this.leafSlot), + value: new Fr(this.value), + leafPreimage: expect.objectContaining({ slot: new Fr(this.matchOrLowLeafSlot) }), + }); + } +} + +describe('buildPublicDataHints', () => { + let publicDataReads: Tuple; + let publicDataUpdateRequests: Tuple; + let expectedHints: Tuple; + + const publicDataLeaves = [ + new PublicDataTreeLeafPreimage(new Fr(22), new Fr(200), new Fr(33), 0n), + new PublicDataTreeLeafPreimage(new Fr(11), new Fr(100), new Fr(22), 0n), + new PublicDataTreeLeafPreimage(new Fr(0), new Fr(0), new Fr(11), 0n), + ]; + + const makePublicDataRead = (leafSlot: number, value: number) => new PublicDataRead(new Fr(leafSlot), new Fr(value)); + const makePublicDataWrite = (leafSlot: number, value: number) => + new PublicDataUpdateRequest(new Fr(leafSlot), new Fr(value)); + + const oracle = { + getMatchOrLowPublicDataMembershipWitness: (leafSlot: bigint) => { + const leafPreimage = publicDataLeaves.find(l => l.slot.toBigInt() <= leafSlot); + return { membershipWitness: {}, leafPreimage } as any; + }, + }; + + const buildHints = () => buildPublicDataHints(oracle, publicDataReads, publicDataUpdateRequests); + + const buildAndCheckHints = async () => { + const hints = await buildHints(); + const partialHints = expectedHints.map(h => h.toExpectedObject()); + expect(hints).toEqual(partialHints); + }; + + beforeEach(() => { + publicDataReads = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, PublicDataRead.empty); + publicDataUpdateRequests = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, PublicDataUpdateRequest.empty); + expectedHints = makeTuple(MAX_PUBLIC_DATA_HINTS, ExpectedHint.empty); + }); + + it('returns empty hints', async () => { + await buildAndCheckHints(); + }); + + it('builds hints for reads for uninitialized slots', async () => { + publicDataReads[0] = makePublicDataRead(12, 0); + publicDataReads[1] = makePublicDataRead(39, 0); + expectedHints[0] = new ExpectedHint(12, 0, 11); + expectedHints[1] = new ExpectedHint(39, 0, 22); + + await buildAndCheckHints(); + }); + + it('builds hints for reads for initialized slots', async () => { + publicDataReads[0] = makePublicDataRead(22, 200); + publicDataReads[1] = makePublicDataRead(11, 100); + expectedHints[0] = new ExpectedHint(22, 200, 22); + expectedHints[1] = new ExpectedHint(11, 100, 11); + + await buildAndCheckHints(); + }); + + it('builds hints for writes to uninitialized slots', async () => { + publicDataUpdateRequests[0] = makePublicDataWrite(5, 500); + publicDataUpdateRequests[1] = makePublicDataWrite(17, 700); + expectedHints[0] = new ExpectedHint(5, 0, 0); + expectedHints[1] = new ExpectedHint(17, 0, 11); + + await buildAndCheckHints(); + }); + + it('builds hints for writes to initialized slots', async () => { + publicDataUpdateRequests[0] = makePublicDataWrite(11, 111); + publicDataUpdateRequests[1] = makePublicDataWrite(22, 222); + expectedHints[0] = new ExpectedHint(11, 100, 11); + expectedHints[1] = new ExpectedHint(22, 200, 22); + + await buildAndCheckHints(); + }); + + it('builds hints for mixed reads and writes', async () => { + publicDataReads[0] = makePublicDataRead(22, 200); + publicDataReads[1] = makePublicDataRead(12, 0); + publicDataReads[2] = makePublicDataRead(39, 0); + publicDataReads[3] = makePublicDataRead(11, 100); + publicDataUpdateRequests[0] = makePublicDataWrite(11, 111); + publicDataUpdateRequests[1] = makePublicDataWrite(5, 500); + publicDataUpdateRequests[2] = makePublicDataWrite(17, 700); + publicDataUpdateRequests[3] = makePublicDataWrite(22, 222); + expectedHints[0] = new ExpectedHint(22, 200, 22); + expectedHints[1] = new ExpectedHint(12, 0, 11); + expectedHints[2] = new ExpectedHint(39, 0, 22); + expectedHints[3] = new ExpectedHint(11, 100, 11); + expectedHints[4] = new ExpectedHint(5, 0, 0); + expectedHints[5] = new ExpectedHint(17, 0, 11); + + await buildAndCheckHints(); + }); +}); diff --git a/yarn-project/circuits.js/src/hints/build_public_data_hints.ts b/yarn-project/circuits.js/src/hints/build_public_data_hints.ts new file mode 100644 index 000000000000..22d69a520bb9 --- /dev/null +++ b/yarn-project/circuits.js/src/hints/build_public_data_hints.ts @@ -0,0 +1,49 @@ +import { padArrayEnd } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/fields'; +import { type Tuple } from '@aztec/foundation/serialize'; + +import { + MAX_PUBLIC_DATA_HINTS, + type MAX_PUBLIC_DATA_READS_PER_TX, + type MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + type PUBLIC_DATA_TREE_HEIGHT, +} from '../constants.gen.js'; +import { + type PublicDataRead, + type PublicDataTreeLeafPreimage, + type PublicDataUpdateRequest, +} from '../structs/index.js'; +import { type MembershipWitness } from '../structs/membership_witness.js'; +import { PublicDataHint } from '../structs/public_data_hint.js'; + +interface PublicDataMembershipWitnessWithPreimage { + membershipWitness: MembershipWitness; + leafPreimage: PublicDataTreeLeafPreimage; +} + +export async function buildPublicDataHints( + oracle: { + getMatchOrLowPublicDataMembershipWitness(leafSlot: bigint): Promise; + }, + publicDataReads: Tuple, + publicDataUpdateRequests: Tuple, +) { + const publicDataLeafSlotSet: Set = new Set(); + [...publicDataReads, ...publicDataUpdateRequests] + .filter(r => !r.isEmpty()) + .forEach(v => { + publicDataLeafSlotSet.add(v.leafSlot.toBigInt()); + }); + const uniquePublicDataLeafSlots = [...publicDataLeafSlotSet]; + + const hints: PublicDataHint[] = []; + for (let i = 0; i < uniquePublicDataLeafSlots.length; i++) { + const leafSlot = uniquePublicDataLeafSlots[i]; + const { membershipWitness, leafPreimage } = await oracle.getMatchOrLowPublicDataMembershipWitness(leafSlot); + const exists = leafPreimage.slot.toBigInt() === leafSlot; + const value = exists ? leafPreimage.value : Fr.ZERO; + hints.push(new PublicDataHint(new Fr(leafSlot), value, 0, membershipWitness, leafPreimage)); + } + + return padArrayEnd(hints, PublicDataHint.empty(), MAX_PUBLIC_DATA_HINTS); +} diff --git a/yarn-project/circuits.js/src/hints/build_public_data_read_request_hints.test.ts b/yarn-project/circuits.js/src/hints/build_public_data_read_request_hints.test.ts new file mode 100644 index 000000000000..164256ede3ee --- /dev/null +++ b/yarn-project/circuits.js/src/hints/build_public_data_read_request_hints.test.ts @@ -0,0 +1,150 @@ +import { makeTuple } from '@aztec/foundation/array'; +import { padArrayEnd } from '@aztec/foundation/collection'; +import { Fr } from '@aztec/foundation/fields'; +import { type Tuple } from '@aztec/foundation/serialize'; + +import { + MAX_PUBLIC_DATA_HINTS, + MAX_PUBLIC_DATA_READS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, +} from '../constants.gen.js'; +import { + LeafDataReadHint, + PendingReadHint, + PublicDataHint, + PublicDataRead, + PublicDataUpdateRequest, + ReadRequestStatus, +} from '../structs/index.js'; +import { buildPublicDataReadRequestHints } from './build_public_data_read_request_hints.js'; + +describe('buildPublicDataReadRequestHints', () => { + let publicDataReads: Tuple; + let expectedStatuses: Tuple; + let expectedPendingHints: Tuple; + let expectedLeafDataHints: Tuple; + + const makePublicDataWrite = (leafSlot: number, value: number) => + new PublicDataUpdateRequest(new Fr(leafSlot), new Fr(value)); + const makePublicDataHint = (slot: number, value: number) => { + const hint = PublicDataHint.empty(); + hint.leafSlot = new Fr(slot); + hint.value = new Fr(value); + return hint; + }; + const makePublicDataRead = (leafSlot: number, value: number) => new PublicDataRead(new Fr(leafSlot), new Fr(value)); + const makePendingHint = (readRequestIndex: number, hintIndex: number) => + new PendingReadHint(readRequestIndex, hintIndex); + const makeLeafDataHint = (readRequestIndex: number, hintIndex: number) => + new LeafDataReadHint(readRequestIndex, hintIndex); + + const publicDataUpdateRequests = padArrayEnd( + [makePublicDataWrite(55, 5555), makePublicDataWrite(77, 7777), makePublicDataWrite(99, 9999)], + PublicDataUpdateRequest.empty(), + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + ); + + const publicDataHints = padArrayEnd( + [ + makePublicDataHint(11, 100), + makePublicDataHint(22, 200), + makePublicDataHint(33, 300), + makePublicDataHint(55, 500), + makePublicDataHint(77, 0), + makePublicDataHint(99, 900), + ], + PublicDataHint.empty(), + MAX_PUBLIC_DATA_HINTS, + ); + + const buildHints = () => buildPublicDataReadRequestHints(publicDataReads, publicDataUpdateRequests, publicDataHints); + + const buildAndCheckHints = () => { + const hints = buildHints(); + expect(hints.readRequestStatuses).toEqual(expectedStatuses); + expect(hints.pendingReadHints).toEqual(expectedPendingHints); + expect(hints.leafDataReadHints).toEqual(expectedLeafDataHints); + }; + + beforeEach(() => { + publicDataReads = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, PublicDataRead.empty); + expectedStatuses = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, ReadRequestStatus.nada); + expectedPendingHints = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => + PendingReadHint.nada(MAX_PUBLIC_DATA_READS_PER_TX), + ); + expectedLeafDataHints = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => + LeafDataReadHint.nada(MAX_PUBLIC_DATA_READS_PER_TX), + ); + }); + + it('returns empty hints', () => { + buildAndCheckHints(); + }); + + it('builds hints for reading pending values', () => { + publicDataReads[0] = makePublicDataRead(77, 7777); + publicDataReads[1] = makePublicDataRead(99, 9999); + publicDataReads[2] = makePublicDataRead(55, 5555); + expectedStatuses[0] = ReadRequestStatus.pending(0); + expectedStatuses[1] = ReadRequestStatus.pending(1); + expectedStatuses[2] = ReadRequestStatus.pending(2); + expectedPendingHints[0] = makePendingHint(0, 1); + expectedPendingHints[1] = makePendingHint(1, 2); + expectedPendingHints[2] = makePendingHint(2, 0); + + buildAndCheckHints(); + }); + + it('builds hints for reading settled or uninitialized values', () => { + publicDataReads[0] = makePublicDataRead(33, 300); + publicDataReads[1] = makePublicDataRead(77, 0); + publicDataReads[2] = makePublicDataRead(55, 500); + publicDataReads[3] = makePublicDataRead(11, 100); + expectedStatuses[0] = ReadRequestStatus.settled(0); + expectedStatuses[1] = ReadRequestStatus.settled(1); + expectedStatuses[2] = ReadRequestStatus.settled(2); + expectedStatuses[3] = ReadRequestStatus.settled(3); + expectedLeafDataHints[0] = makeLeafDataHint(0, 2); + expectedLeafDataHints[1] = makeLeafDataHint(1, 4); + expectedLeafDataHints[2] = makeLeafDataHint(2, 3); + expectedLeafDataHints[3] = makeLeafDataHint(3, 0); + + buildAndCheckHints(); + }); + + it('builds hints for reading pending and settled values', () => { + publicDataReads[0] = makePublicDataRead(55, 500); + publicDataReads[1] = makePublicDataRead(55, 5555); + publicDataReads[2] = makePublicDataRead(77, 0); + publicDataReads[3] = makePublicDataRead(11, 100); + publicDataReads[4] = makePublicDataRead(99, 9999); + publicDataReads[5] = makePublicDataRead(77, 7777); + publicDataReads[6] = makePublicDataRead(11, 100); + expectedStatuses[0] = ReadRequestStatus.settled(0); + expectedStatuses[1] = ReadRequestStatus.pending(0); + expectedStatuses[2] = ReadRequestStatus.settled(1); + expectedStatuses[3] = ReadRequestStatus.settled(2); + expectedStatuses[4] = ReadRequestStatus.pending(1); + expectedStatuses[5] = ReadRequestStatus.pending(2); + expectedStatuses[6] = ReadRequestStatus.settled(3); + expectedPendingHints[0] = makePendingHint(1, 0); + expectedPendingHints[1] = makePendingHint(4, 2); + expectedPendingHints[2] = makePendingHint(5, 1); + expectedLeafDataHints[0] = makeLeafDataHint(0, 3); + expectedLeafDataHints[1] = makeLeafDataHint(2, 4); + expectedLeafDataHints[2] = makeLeafDataHint(3, 0); + expectedLeafDataHints[3] = makeLeafDataHint(6, 0); + + buildAndCheckHints(); + }); + + it('throws if reading unknown slot', () => { + publicDataReads[0] = makePublicDataRead(123, 100); + expect(() => buildHints()).toThrow('Cannot find a pending write or a data hint for the read request.'); + }); + + it('throws if reading unknown value', () => { + publicDataReads[0] = makePublicDataRead(11, 1111); + expect(() => buildHints()).toThrow('Value being read does not match existing public data or pending writes.'); + }); +}); diff --git a/yarn-project/circuits.js/src/hints/build_public_data_read_request_hints.ts b/yarn-project/circuits.js/src/hints/build_public_data_read_request_hints.ts new file mode 100644 index 000000000000..4f7b15f312b8 --- /dev/null +++ b/yarn-project/circuits.js/src/hints/build_public_data_read_request_hints.ts @@ -0,0 +1,45 @@ +import { type Tuple } from '@aztec/foundation/serialize'; + +import { + type MAX_PUBLIC_DATA_HINTS, + type MAX_PUBLIC_DATA_READS_PER_TX, + type MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, +} from '../constants.gen.js'; +import { + type PublicDataRead, + PublicDataReadRequestHintsBuilder, + type PublicDataUpdateRequest, +} from '../structs/index.js'; +import { type PublicDataHint } from '../structs/public_data_hint.js'; +import { countAccumulatedItems } from '../utils/index.js'; + +export function buildPublicDataReadRequestHints( + publicDataReads: Tuple, + publicDataUpdateRequests: Tuple, + publicDataHints: Tuple, +) { + const builder = new PublicDataReadRequestHintsBuilder(); + + const numReadRequests = countAccumulatedItems(publicDataReads); + for (let i = 0; i < numReadRequests; ++i) { + const rr = publicDataReads[i]; + // TODO: Add counters to reads and writes. + const writeIndex = publicDataUpdateRequests.findIndex( + w => w.leafSlot.equals(rr.leafSlot) && w.newValue.equals(rr.value), + ); + if (writeIndex !== -1) { + builder.addPendingReadRequest(i, writeIndex); + } else { + const hintIndex = publicDataHints.findIndex(h => h.leafSlot.equals(rr.leafSlot)); + if (hintIndex === -1) { + throw new Error('Cannot find a pending write or a data hint for the read request.'); + } + if (!publicDataHints[hintIndex].value.equals(rr.value)) { + throw new Error('Value being read does not match existing public data or pending writes.'); + } + builder.addLeafDataReadRequest(i, hintIndex); + } + } + + return builder.toHints(); +} diff --git a/yarn-project/circuits.js/src/hints/index.ts b/yarn-project/circuits.js/src/hints/index.ts index 476edce05e9c..d9378ed85b5f 100644 --- a/yarn-project/circuits.js/src/hints/index.ts +++ b/yarn-project/circuits.js/src/hints/index.ts @@ -1,2 +1,3 @@ export * from './build_hints.js'; -export * from '../utils/index.js'; +export * from './build_public_data_hints.js'; +export * from './build_public_data_read_request_hints.js'; diff --git a/yarn-project/circuits.js/src/index.ts b/yarn-project/circuits.js/src/index.ts index 3b6fdbcd0e63..d4c939ef836a 100644 --- a/yarn-project/circuits.js/src/index.ts +++ b/yarn-project/circuits.js/src/index.ts @@ -6,3 +6,4 @@ export * from './interfaces/index.js'; export * from './keys/index.js'; export * from './structs/index.js'; export * from './types/index.js'; +export * from './utils/index.js'; diff --git a/yarn-project/circuits.js/src/scripts/constants.in.ts b/yarn-project/circuits.js/src/scripts/constants.in.ts index a5fadc66e2a4..33ede0eded4c 100644 --- a/yarn-project/circuits.js/src/scripts/constants.in.ts +++ b/yarn-project/circuits.js/src/scripts/constants.in.ts @@ -122,7 +122,7 @@ function parseNoirFile(fileContent: string): ParsedContent { return; } - const [, name, _type, value] = line.match(/global\s+(\w+)(\s*:\s*\w+)?\s*=\s*(0x[a-fA-F0-9]+|[\d_]+);/) || []; + const [, name, _type, value] = line.match(/global\s+(\w+)(\s*:\s*\w+)?\s*=\s*(.+?);/) || []; if (!name || !value) { // eslint-disable-next-line no-console diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/private_call_stack_item.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/private_call_stack_item.test.ts.snap index d623cd914682..46d4e2bf80d5 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/private_call_stack_item.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/private_call_stack_item.test.ts.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PrivateCallStackItem computes empty item hash 1`] = `Fr<0x229caf5ebf8961d7cbfdf2f7a5db62810d130b598900a0be1137394a43371bc6>`; +exports[`PrivateCallStackItem computes empty item hash 1`] = `Fr<0x24185d8e88fe796dec6e400f3d6c7572cefd85cea80591f268f08a9350992c48>`; -exports[`PrivateCallStackItem computes hash 1`] = `Fr<0x20ca153bfa0c8bcabe989feb102b81c4c78e08004ee2fdc2f09b93b635e1595a>`; +exports[`PrivateCallStackItem computes hash 1`] = `Fr<0x2e5307580ef277146cc3c6a9d9210c6e317d9b6a033755f509e6161d0eaf576a>`; diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/private_circuit_public_inputs.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/private_circuit_public_inputs.test.ts.snap index c965dd0e9b3c..4e423c22442c 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/private_circuit_public_inputs.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/private_circuit_public_inputs.test.ts.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PrivateCircuitPublicInputs computes empty inputs hash 1`] = `Fr<0x13ba2af75e4afaa4e52dd1afa083e87706cdbab1a33442025dc3a9bbb546d207>`; +exports[`PrivateCircuitPublicInputs computes empty inputs hash 1`] = `Fr<0x24ea9ab3fc039778bef8e7212f6a09feec1019db19b449333b523a08b812ee88>`; -exports[`PrivateCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x0f250912b993f2334ad0aeb39e1051f7db753a7302d00b063834fac578e36f1c>`; +exports[`PrivateCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x144c861f88d1ba68fc7e72f7a578546207bbf785e4a23278601662d85cd25d12>`; diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/public_call_stack_item.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/public_call_stack_item.test.ts.snap index 589fe9bb59e9..230870d273c9 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/public_call_stack_item.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/public_call_stack_item.test.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PublicCallStackItem Computes a callstack item hash 1`] = `"0x1a7b9d0cd965f512a3b3ed70333198a2a69bd4f9e70be68379c54e68a7b07a4c"`; +exports[`PublicCallStackItem Computes a callstack item hash 1`] = `"0x0c0d60d424315af5f106a802b250c27c613a9ec1c0f583c6ad806cf22fe66a13"`; -exports[`PublicCallStackItem Computes a callstack item request hash 1`] = `"0x151bc9ee42eb63112fb2a350dcaa33c4c4b81cc37ded8773e785f47029f35983"`; +exports[`PublicCallStackItem Computes a callstack item request hash 1`] = `"0x134d01b778664dbc1ffa953008ce28f72b0cb258533776f10df59a59d791e972"`; -exports[`PublicCallStackItem computes hash 1`] = `Fr<0x107c825cf4cf15d2618c5828eced84edc7dd29c277ff1f6171c6354237174b7a>`; +exports[`PublicCallStackItem computes hash 1`] = `Fr<0x2c7d4c31cdb4762c88686417968228c7d102e205e89cb157a34365eef5bfb15c>`; diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/public_circuit_public_inputs.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/public_circuit_public_inputs.test.ts.snap index 962240da2684..057d7b9aeac2 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/public_circuit_public_inputs.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/public_circuit_public_inputs.test.ts.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PublicCircuitPublicInputs computes empty item hash 1`] = `Fr<0x2745ec62624afeb19b86af3d440db1f8c3432e1d17a074c75cb8f44999fd3fae>`; +exports[`PublicCircuitPublicInputs computes empty item hash 1`] = `Fr<0x1092820bc987359300ff136abf020d58218e1b3484e03d756c76e81ac56ccbf7>`; -exports[`PublicCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x0082fbb87371d9f98bb2d7c0b6e8f5e12f21f67085b5bd42931596f3d2e5eb9b>`; +exports[`PublicCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x251dcf0ab2afb050857487a1545e99cc12ddd7655154f89b8aab1d7872845173>`; diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/tx_request.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/tx_request.test.ts.snap index 06f830fd9cb6..7bf6df6c4a46 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/tx_request.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/tx_request.test.ts.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`TxRequest compute hash 1`] = `"0x20af6f595c396494f1177fa196d17e98d55a2416b28c262b76e78a36d6c01daa"`; +exports[`TxRequest compute hash 1`] = `"0x03b678e327818eb368f9eac21839ee67a98968318f0dcd76c89d3fcf66af7257"`; diff --git a/yarn-project/circuits.js/src/structs/call_context.ts b/yarn-project/circuits.js/src/structs/call_context.ts index 8a3326759883..b542a46b1e06 100644 --- a/yarn-project/circuits.js/src/structs/call_context.ts +++ b/yarn-project/circuits.js/src/structs/call_context.ts @@ -6,6 +6,7 @@ import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from import { type FieldsOf } from '@aztec/foundation/types'; import { CALL_CONTEXT_LENGTH } from '../constants.gen.js'; +import { Gas } from './gas.js'; import { GasSettings } from './gas_settings.js'; /** @@ -31,6 +32,8 @@ export class CallContext { * Function selector of the function being called. */ public functionSelector: FunctionSelector, + /** How much gas is available for execution of this function. */ + public gasLeft: Gas, /** * Determines whether the call is a delegate call (see Ethereum's delegate call opcode for more information). */ @@ -61,6 +64,7 @@ export class CallContext { AztecAddress.ZERO, EthAddress.ZERO, FunctionSelector.empty(), + Gas.empty(), false, false, 0, @@ -75,6 +79,7 @@ export class CallContext { this.storageContractAddress.isZero() && this.portalContractAddress.isZero() && this.functionSelector.isEmpty() && + this.gasLeft.isEmpty() && Fr.ZERO && this.gasSettings.isEmpty() && this.transactionFee.isZero() @@ -91,6 +96,7 @@ export class CallContext { fields.storageContractAddress, fields.portalContractAddress, fields.functionSelector, + fields.gasLeft, fields.isDelegateCall, fields.isStaticCall, fields.sideEffectCounter, @@ -129,6 +135,7 @@ export class CallContext { reader.readObject(AztecAddress), reader.readObject(EthAddress), reader.readObject(FunctionSelector), + reader.readObject(Gas), reader.readBoolean(), reader.readBoolean(), reader.readNumber(), @@ -144,6 +151,7 @@ export class CallContext { reader.readObject(AztecAddress), reader.readObject(EthAddress), reader.readObject(FunctionSelector), + reader.readObject(Gas), reader.readBoolean(), reader.readBoolean(), reader.readU32(), @@ -158,6 +166,7 @@ export class CallContext { callContext.storageContractAddress.equals(this.storageContractAddress) && callContext.portalContractAddress.equals(this.portalContractAddress) && callContext.functionSelector.equals(this.functionSelector) && + callContext.gasLeft.equals(this.gasLeft) && callContext.isDelegateCall === this.isDelegateCall && callContext.isStaticCall === this.isStaticCall && callContext.sideEffectCounter === this.sideEffectCounter && diff --git a/yarn-project/circuits.js/src/structs/contract_storage_read.ts b/yarn-project/circuits.js/src/structs/contract_storage_read.ts index 2c376a1d3f5c..52d708f0ef17 100644 --- a/yarn-project/circuits.js/src/structs/contract_storage_read.ts +++ b/yarn-project/circuits.js/src/structs/contract_storage_read.ts @@ -1,3 +1,4 @@ +import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; @@ -24,6 +25,7 @@ export class ContractStorageRead { * Note: Not serialized */ public readonly sideEffectCounter?: number, + public contractAddress?: AztecAddress, // TODO: Should not be optional. This is a temporary hack to silo the storage slot with the correct address for nested executions. ) {} static from(args: { @@ -39,8 +41,9 @@ export class ContractStorageRead { * Optional side effect counter tracking position of this event in tx execution. */ sideEffectCounter?: number; + contractAddress?: AztecAddress; }) { - return new ContractStorageRead(args.storageSlot, args.currentValue, args.sideEffectCounter); + return new ContractStorageRead(args.storageSlot, args.currentValue, args.sideEffectCounter, args.contractAddress); } toBuffer() { diff --git a/yarn-project/circuits.js/src/structs/contract_storage_update_request.ts b/yarn-project/circuits.js/src/structs/contract_storage_update_request.ts index 8508fa8c7b8a..378279d55bb1 100644 --- a/yarn-project/circuits.js/src/structs/contract_storage_update_request.ts +++ b/yarn-project/circuits.js/src/structs/contract_storage_update_request.ts @@ -1,3 +1,4 @@ +import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { type FieldsOf } from '@aztec/foundation/types'; @@ -24,6 +25,7 @@ export class ContractStorageUpdateRequest { * Optional side effect counter tracking position of this event in tx execution. */ public readonly sideEffectCounter?: number, + public contractAddress?: AztecAddress, // TODO: Should not be optional. This is a temporary hack to silo the storage slot with the correct address for nested executions. ) {} toBuffer() { @@ -50,7 +52,7 @@ export class ContractStorageUpdateRequest { * @returns The array. */ static getFields(fields: FieldsOf) { - return [fields.storageSlot, fields.newValue, fields.sideEffectCounter] as const; + return [fields.storageSlot, fields.newValue, fields.sideEffectCounter, fields.contractAddress] as const; } static empty() { diff --git a/yarn-project/circuits.js/src/structs/gas.ts b/yarn-project/circuits.js/src/structs/gas.ts new file mode 100644 index 000000000000..5924282216a7 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/gas.ts @@ -0,0 +1,67 @@ +import { type Fr } from '@aztec/foundation/fields'; +import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize'; +import { type FieldsOf } from '@aztec/foundation/types'; + +import { inspect } from 'util'; + +import { type UInt32 } from './shared.js'; + +/** Gas amounts in each dimension. */ +export class Gas { + constructor(public readonly daGas: UInt32, public readonly l1Gas: UInt32, public readonly l2Gas: UInt32) {} + + equals(other: Gas) { + return this.daGas === other.daGas && this.l1Gas === other.l1Gas && this.l2Gas === other.l2Gas; + } + + static from(fields: FieldsOf) { + return new Gas(fields.daGas, fields.l1Gas, fields.l2Gas); + } + + static empty() { + return new Gas(0, 0, 0); + } + + /** Returns large enough gas amounts for testing purposes. */ + static test() { + return new Gas(1e9, 1e9, 1e9); + } + + isEmpty() { + return this.daGas === 0 && this.l1Gas === 0 && this.l2Gas === 0; + } + + static fromBuffer(buffer: Buffer | BufferReader): Gas { + const reader = BufferReader.asReader(buffer); + return new Gas(reader.readNumber(), reader.readNumber(), reader.readNumber()); + } + + toBuffer() { + return serializeToBuffer(this.daGas, this.l1Gas, this.l2Gas); + } + + [inspect.custom]() { + return `Gas { daGas=${this.daGas} l1Gas=${this.l1Gas} l2Gas=${this.l2Gas} }`; + } + + add(other: Gas) { + return new Gas(this.daGas + other.daGas, this.l1Gas + other.l1Gas, this.l2Gas + other.l2Gas); + } + + sub(other: Gas) { + return new Gas(this.daGas - other.daGas, this.l1Gas - other.l1Gas, this.l2Gas - other.l2Gas); + } + + mul(scalar: number) { + return new Gas(Math.ceil(this.daGas * scalar), Math.ceil(this.l1Gas * scalar), Math.ceil(this.l2Gas * scalar)); + } + + toFields() { + return serializeToFields(this.daGas, this.l1Gas, this.l2Gas); + } + + static fromFields(fields: Fr[] | FieldReader) { + const reader = FieldReader.asReader(fields); + return new Gas(reader.readU32(), reader.readU32(), reader.readU32()); + } +} diff --git a/yarn-project/circuits.js/src/structs/gas_fees.ts b/yarn-project/circuits.js/src/structs/gas_fees.ts index 89a7f9ff7b2d..ee5489d47b28 100644 --- a/yarn-project/circuits.js/src/structs/gas_fees.ts +++ b/yarn-project/circuits.js/src/structs/gas_fees.ts @@ -20,6 +20,11 @@ export class GasFees { return new GasFees(Fr.ZERO, Fr.ZERO, Fr.ZERO); } + /** Fixed gas fee values used until we define how gas fees in the protocol are computed. */ + static default() { + return new GasFees(Fr.ONE, Fr.ONE, Fr.ONE); + } + isEmpty() { return this.feePerDaGas.isZero() && this.feePerL1Gas.isZero() && this.feePerL2Gas.isZero(); } diff --git a/yarn-project/circuits.js/src/structs/gas_settings.ts b/yarn-project/circuits.js/src/structs/gas_settings.ts index 68cbc3fad420..80a57f0c19b0 100644 --- a/yarn-project/circuits.js/src/structs/gas_settings.ts +++ b/yarn-project/circuits.js/src/structs/gas_settings.ts @@ -3,6 +3,7 @@ import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from import { type FieldsOf } from '@aztec/foundation/types'; import { GAS_SETTINGS_LENGTH } from '../constants.gen.js'; +import { Gas } from './gas.js'; import { type UInt32 } from './shared.js'; /** Gas usage and fees limits set by the transaction sender for different dimensions and phases. */ @@ -14,6 +15,28 @@ export class GasSettings { public readonly inclusionFee: Fr, ) {} + static new(args: { + da: FieldsOf; + l1: FieldsOf; + l2: FieldsOf; + inclusionFee: Fr; + }) { + return new GasSettings( + DimensionGasSettings.from(args.da), + DimensionGasSettings.from(args.l1), + DimensionGasSettings.from(args.l2), + args.inclusionFee, + ); + } + + /** Returns the maximum fee to be paid according to gas limits and max fees set. */ + getFeeLimit() { + return [this.da, this.l1, this.l2] + .reduce((acc, dimension) => acc.add(dimension.getFeeLimit()), Fr.ZERO) + .add(this.inclusionFee); + } + + /** Zero-value gas settings. */ static empty() { return new GasSettings( DimensionGasSettings.empty(), @@ -23,6 +46,26 @@ export class GasSettings { ); } + /** Default gas settings to use when user has not provided them. */ + static default() { + return new GasSettings( + DimensionGasSettings.default(), + DimensionGasSettings.default(), + DimensionGasSettings.default(), + Fr.ONE, + ); + } + + /** Gas settings to use for simulating a contract call. */ + static simulation() { + return new GasSettings( + DimensionGasSettings.simulation(), + DimensionGasSettings.simulation(), + DimensionGasSettings.simulation(), + Fr.ONE, + ); + } + isEmpty() { return this.da.isEmpty() && this.l1.isEmpty() && this.l2.isEmpty() && this.inclusionFee.isZero(); } @@ -73,6 +116,25 @@ export class GasSettings { static getFields(fields: FieldsOf) { return [fields.da, fields.l1, fields.l2, fields.inclusionFee] as const; } + + /** Returns total gas limits. */ + getLimits(): Gas { + return new Gas(this.da.gasLimit, this.l1.gasLimit, this.l2.gasLimit); + } + + /** Returns how much gas is available for execution of setup and app phases (ie total limit minus teardown). */ + getInitialAvailable(): Gas { + return new Gas( + this.da.gasLimit - this.da.teardownGasLimit, + this.l1.gasLimit - this.l1.teardownGasLimit, + this.l2.gasLimit - this.l2.teardownGasLimit, + ); + } + + /** Returns how much gas is available for execution of teardown phase. */ + getTeardownLimits(): Gas { + return new Gas(this.da.teardownGasLimit, this.l1.teardownGasLimit, this.l2.teardownGasLimit); + } } /** Gas usage and fees limits set by the transaction sender for different phases on a specific dimension. */ @@ -81,7 +143,23 @@ export class DimensionGasSettings { public readonly gasLimit: UInt32, public readonly teardownGasLimit: UInt32, public readonly maxFeePerGas: Fr, - ) {} + ) { + if (teardownGasLimit > gasLimit) { + throw new Error(`Teardown gas limit ${teardownGasLimit} is greater than gas limit ${gasLimit}`); + } + } + + static default() { + return new DimensionGasSettings(1e9, 1e8, Fr.ONE); + } + + static simulation() { + return new DimensionGasSettings(1e9, 1e8, Fr.ONE); + } + + getFeeLimit() { + return this.maxFeePerGas.mul(new Fr(this.gasLimit + this.teardownGasLimit)); + } static empty() { return new DimensionGasSettings(0, 0, Fr.ZERO); @@ -120,4 +198,8 @@ export class DimensionGasSettings { static getFields(fields: FieldsOf) { return [fields.gasLimit, fields.teardownGasLimit, fields.maxFeePerGas] as const; } + + static from(fields: FieldsOf) { + return new DimensionGasSettings(fields.gasLimit, fields.teardownGasLimit, fields.maxFeePerGas); + } } diff --git a/yarn-project/circuits.js/src/structs/gas_used.ts b/yarn-project/circuits.js/src/structs/gas_used.ts deleted file mode 100644 index 46100b229150..000000000000 --- a/yarn-project/circuits.js/src/structs/gas_used.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { type FieldsOf } from '@aztec/foundation/types'; - -import { inspect } from 'util'; - -import { type UInt32 } from './shared.js'; - -/** Gas in each dimension used so far in the context of the current transaction or phase. */ -export class GasUsed { - constructor(public readonly daGas: UInt32, public readonly l1Gas: UInt32, public readonly l2Gas: UInt32) {} - - static from(fields: FieldsOf) { - return new GasUsed(fields.daGas, fields.l1Gas, fields.l2Gas); - } - - static empty() { - return new GasUsed(0, 0, 0); - } - - isEmpty() { - return this.daGas === 0 && this.l1Gas === 0 && this.l2Gas === 0; - } - - static fromBuffer(buffer: Buffer | BufferReader): GasUsed { - const reader = BufferReader.asReader(buffer); - return new GasUsed(reader.readNumber(), reader.readNumber(), reader.readNumber()); - } - - toBuffer() { - return serializeToBuffer(this.daGas, this.l1Gas, this.l2Gas); - } - - [inspect.custom]() { - return `GasUsed { daGas=${this.daGas} l1Gas=${this.l1Gas} l2Gas=${this.l2Gas} }`; - } -} diff --git a/yarn-project/circuits.js/src/structs/index.ts b/yarn-project/circuits.js/src/structs/index.ts index e2c688921c54..400c60e8ac9b 100644 --- a/yarn-project/circuits.js/src/structs/index.ts +++ b/yarn-project/circuits.js/src/structs/index.ts @@ -9,7 +9,7 @@ export * from './contract_storage_update_request.js'; export * from './function_data.js'; export * from './gas_fees.js'; export * from './gas_settings.js'; -export * from './gas_used.js'; +export * from './gas.js'; export * from './global_variables.js'; export * from './header.js'; export * from './kernel/combined_accumulated_data.js'; @@ -47,7 +47,9 @@ export * from './proof.js'; export * from './public_call_request.js'; export * from './public_call_stack_item.js'; export * from './public_circuit_public_inputs.js'; +export * from './public_data_hint.js'; export * from './public_data_read_request.js'; +export * from './public_data_read_request_hints.js'; export * from './public_data_update_request.js'; export * from './read_request.js'; export * from './read_request_hints.js'; diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts index 8599e3e0de84..3c4d58cf3ed8 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts @@ -9,7 +9,7 @@ import { MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, } from '../../constants.gen.js'; -import { GasUsed } from '../gas_used.js'; +import { Gas } from '../gas.js'; import { PublicDataUpdateRequest } from '../public_data_update_request.js'; /** @@ -53,7 +53,7 @@ export class CombinedAccumulatedData { public publicDataUpdateRequests: Tuple, /** Gas used during this transaction */ - public gasUsed: GasUsed, + public gasUsed: Gas, ) {} toBuffer() { @@ -90,7 +90,7 @@ export class CombinedAccumulatedData { Fr.fromBuffer(reader), Fr.fromBuffer(reader), reader.readArray(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest), - reader.readObject(GasUsed), + reader.readObject(Gas), ); } @@ -113,7 +113,7 @@ export class CombinedAccumulatedData { Fr.zero(), Fr.zero(), makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), - GasUsed.empty(), + Gas.empty(), ); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts index 4baa7593deba..6534f7c90a0e 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts @@ -24,7 +24,7 @@ export class CombinedConstantData { public txContext: TxContext, /** Gas limits and max prices for this transaction as set by the sender. */ - public readonly gasSettings: GasSettings, + public gasSettings: GasSettings, ) {} toBuffer() { diff --git a/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts index cb59c58b76d7..84637a61f919 100644 --- a/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts @@ -1,6 +1,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { AggregationObject } from '../aggregation_object.js'; +import { PartialStateReference } from '../partial_state_reference.js'; import { RevertCode } from '../revert_code.js'; import { RollupValidationRequests } from '../rollup_validation_requests.js'; import { CombinedAccumulatedData } from './combined_accumulated_data.js'; @@ -28,6 +29,7 @@ export class KernelCircuitPublicInputs { * Data which is not modified by the circuits. */ public constants: CombinedConstantData, + public startState: PartialStateReference, /** * Flag indicating whether the transaction reverted. */ @@ -44,6 +46,7 @@ export class KernelCircuitPublicInputs { this.rollupValidationRequests, this.end, this.constants, + this.startState, this.revertCode, ); } @@ -60,6 +63,7 @@ export class KernelCircuitPublicInputs { reader.readObject(RollupValidationRequests), reader.readObject(CombinedAccumulatedData), reader.readObject(CombinedConstantData), + reader.readObject(PartialStateReference), reader.readObject(RevertCode), ); } @@ -70,6 +74,7 @@ export class KernelCircuitPublicInputs { RollupValidationRequests.empty(), CombinedAccumulatedData.empty(), CombinedConstantData.empty(), + PartialStateReference.empty(), RevertCode.OK, ); } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts index 688aa74558cf..d52cc104bc7d 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts @@ -3,15 +3,17 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { + MAX_ENCRYPTED_LOGS_PER_TX, type MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX, } from '../../constants.gen.js'; import { CallRequest } from '../call_request.js'; -import { GasUsed } from '../gas_used.js'; +import { Gas } from '../gas.js'; import { SideEffect, SideEffectLinkedToNoteHash } from '../side_effects.js'; /** @@ -36,12 +38,12 @@ export class PrivateAccumulatedData { * Accumulated encrypted logs hash from all the previous kernel iterations. * Note: Represented as a tuple of 2 fields in order to fit in all of the 256 bits of sha256 hash. */ - public encryptedLogsHash: Fr, + public encryptedLogsHashes: Tuple, /** * Accumulated unencrypted logs hash from all the previous kernel iterations. * Note: Represented as a tuple of 2 fields in order to fit in all of the 256 bits of sha256 hash. */ - public unencryptedLogsHash: Fr, + public unencryptedLogsHashes: Tuple, /** * Total accumulated length of the encrypted log preimages emitted in all the previous kernel iterations */ @@ -61,7 +63,7 @@ export class PrivateAccumulatedData { public publicCallStack: Tuple, /** Gas used so far by this transaction. */ - public gasUsed: GasUsed, + public gasUsed: Gas, ) {} toBuffer() { @@ -69,8 +71,8 @@ export class PrivateAccumulatedData { this.newNoteHashes, this.newNullifiers, this.newL2ToL1Msgs, - this.encryptedLogsHash, - this.unencryptedLogsHash, + this.encryptedLogsHashes, + this.unencryptedLogsHashes, this.encryptedLogPreimagesLength, this.unencryptedLogPreimagesLength, this.privateCallStack, @@ -94,13 +96,13 @@ export class PrivateAccumulatedData { reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr), - Fr.fromBuffer(reader), - Fr.fromBuffer(reader), + reader.readArray(MAX_ENCRYPTED_LOGS_PER_TX, SideEffect), + reader.readArray(MAX_UNENCRYPTED_LOGS_PER_TX, SideEffect), Fr.fromBuffer(reader), Fr.fromBuffer(reader), reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), - reader.readObject(GasUsed), + reader.readObject(Gas), ); } @@ -118,13 +120,13 @@ export class PrivateAccumulatedData { makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), - Fr.zero(), - Fr.zero(), + makeTuple(MAX_ENCRYPTED_LOGS_PER_TX, SideEffect.empty), + makeTuple(MAX_UNENCRYPTED_LOGS_PER_TX, SideEffect.empty), Fr.zero(), Fr.zero(), makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), - GasUsed.empty(), + Gas.empty(), ); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts index cabf3d15f7ff..561b3bf0b25c 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts @@ -2,10 +2,12 @@ import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { + MAX_ENCRYPTED_LOGS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX, } from '../../constants.gen.js'; import { type GrumpkinPrivateKey } from '../../types/grumpkin_private_key.js'; import { countAccumulatedItems } from '../../utils/index.js'; @@ -50,6 +52,22 @@ export class PrivateKernelTailCircuitPrivateInputs { * Contains hints for the transient nullifiers to localize corresponding commitments. */ public nullifierCommitmentHints: Tuple, + /** + * The sorted encrypted log hashes. + */ + public sortedEncryptedLogHashes: Tuple, + /** + * The sorted encrypted log hashes indexes. Maps original to sorted. + */ + public sortedEncryptedLogHashesIndexes: Tuple, + /** + * The sorted unencrypted log hashes. + */ + public sortedUnencryptedLogHashes: Tuple, + /** + * The sorted encrypted log hashes indexes. Maps original to sorted. + */ + public sortedUnencryptedLogHashesIndexes: Tuple, /** * The master nullifier secret keys for the nullifier key validation requests. */ @@ -74,6 +92,10 @@ export class PrivateKernelTailCircuitPrivateInputs { this.sortedNewNullifiersIndexes, this.nullifierReadRequestHints, this.nullifierCommitmentHints, + this.sortedEncryptedLogHashes, + this.sortedEncryptedLogHashesIndexes, + this.sortedUnencryptedLogHashes, + this.sortedUnencryptedLogHashesIndexes, this.masterNullifierSecretKeys, ); } @@ -94,6 +116,10 @@ export class PrivateKernelTailCircuitPrivateInputs { reader.readNumbers(MAX_NEW_NULLIFIERS_PER_TX), reader.readObject({ fromBuffer: nullifierReadRequestHintsFromBuffer }), reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, Fr), + reader.readArray(MAX_ENCRYPTED_LOGS_PER_TX, SideEffect), + reader.readNumbers(MAX_ENCRYPTED_LOGS_PER_TX), + reader.readArray(MAX_UNENCRYPTED_LOGS_PER_TX, SideEffect), + reader.readNumbers(MAX_UNENCRYPTED_LOGS_PER_TX), reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, GrumpkinScalar), ); } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts index cc7ac7fb8b4f..f064b5ee6ec2 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts @@ -3,6 +3,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { MAX_NEW_NULLIFIERS_PER_TX } from '../../constants.gen.js'; import { countAccumulatedItems, mergeAccumulatedData } from '../../utils/index.js'; import { AggregationObject } from '../aggregation_object.js'; +import { PartialStateReference } from '../partial_state_reference.js'; import { RevertCode } from '../revert_code.js'; import { RollupValidationRequests } from '../rollup_validation_requests.js'; import { ValidationRequests } from '../validation_requests.js'; @@ -135,6 +136,7 @@ export class PrivateKernelTailCircuitPublicInputs { this.forRollup.rollupValidationRequests, this.forRollup.end, this.constants, + PartialStateReference.empty(), this.revertCode, ); } diff --git a/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts index 82c924c2d587..7173ba93f71e 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts @@ -5,15 +5,17 @@ import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/s import { inspect } from 'util'; import { + MAX_ENCRYPTED_LOGS_PER_TX, type MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX, } from '../../constants.gen.js'; import { CallRequest } from '../call_request.js'; -import { GasUsed } from '../gas_used.js'; +import { Gas } from '../gas.js'; import { PublicDataUpdateRequest } from '../public_data_update_request.js'; import { SideEffect, SideEffectLinkedToNoteHash } from '../side_effects.js'; @@ -35,12 +37,12 @@ export class PublicAccumulatedData { * Accumulated encrypted logs hash from all the previous kernel iterations. * Note: Represented as a tuple of 2 fields in order to fit in all of the 256 bits of sha256 hash. */ - public encryptedLogsHash: Fr, + public encryptedLogsHashes: Tuple, /** * Accumulated unencrypted logs hash from all the previous kernel iterations. * Note: Represented as a tuple of 2 fields in order to fit in all of the 256 bits of sha256 hash. */ - public unencryptedLogsHash: Fr, + public unencryptedLogsHashes: Tuple, /** * Total accumulated length of the encrypted log preimages emitted in all the previous kernel iterations */ @@ -59,7 +61,7 @@ export class PublicAccumulatedData { public publicCallStack: Tuple, /** Gas used so far by the transaction. */ - public gasUsed: GasUsed, + public gasUsed: Gas, ) {} toBuffer() { @@ -67,8 +69,8 @@ export class PublicAccumulatedData { this.newNoteHashes, this.newNullifiers, this.newL2ToL1Msgs, - this.encryptedLogsHash, - this.unencryptedLogsHash, + this.encryptedLogsHashes, + this.unencryptedLogsHashes, this.encryptedLogPreimagesLength, this.unencryptedLogPreimagesLength, this.publicDataUpdateRequests, @@ -86,8 +88,8 @@ export class PublicAccumulatedData { this.newNoteHashes.every(x => x.isEmpty()) && this.newNullifiers.every(x => x.isEmpty()) && this.newL2ToL1Msgs.every(x => x.isZero()) && - this.encryptedLogsHash.isZero() && - this.unencryptedLogsHash.isZero() && + this.encryptedLogsHashes.every(x => x.isEmpty()) && + this.unencryptedLogsHashes.every(x => x.isEmpty()) && this.encryptedLogPreimagesLength.isZero() && this.unencryptedLogPreimagesLength.isZero() && this.publicDataUpdateRequests.every(x => x.isEmpty()) && @@ -102,8 +104,8 @@ export class PublicAccumulatedData { newNoteHashes: [${this.newNoteHashes.map(h => h.toString()).join(', ')}], newNullifiers: [${this.newNullifiers.map(h => h.toString()).join(', ')}], newL2ToL1Msgs: [${this.newL2ToL1Msgs.map(h => h.toString()).join(', ')}], - encryptedLogsHash: [${this.encryptedLogsHash}], - unencryptedLogsHash: [${this.unencryptedLogsHash}], + encryptedLogsHashes: [${this.encryptedLogsHashes.map(h => h.toString()).join(', ')}], + unencryptedLogsHashes: [${this.unencryptedLogsHashes.map(h => h.toString()).join(', ')}], encryptedLogPreimagesLength: ${this.encryptedLogPreimagesLength} unencryptedLogPreimagesLength: ${this.unencryptedLogPreimagesLength} publicDataUpdateRequests: [${this.publicDataUpdateRequests.map(h => h.toString()).join(', ')}], @@ -123,13 +125,13 @@ export class PublicAccumulatedData { reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr), - Fr.fromBuffer(reader), - Fr.fromBuffer(reader), + reader.readArray(MAX_ENCRYPTED_LOGS_PER_TX, SideEffect), + reader.readArray(MAX_UNENCRYPTED_LOGS_PER_TX, SideEffect), Fr.fromBuffer(reader), Fr.fromBuffer(reader), reader.readArray(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), - reader.readObject(GasUsed), + reader.readObject(Gas), ); } @@ -147,13 +149,13 @@ export class PublicAccumulatedData { makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), - Fr.zero(), - Fr.zero(), + makeTuple(MAX_ENCRYPTED_LOGS_PER_TX, SideEffect.empty), + makeTuple(MAX_UNENCRYPTED_LOGS_PER_TX, SideEffect.empty), Fr.zero(), Fr.zero(), makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), - GasUsed.empty(), + Gas.empty(), ); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/public_call_data.test.ts b/yarn-project/circuits.js/src/structs/kernel/public_call_data.test.ts new file mode 100644 index 000000000000..cafa167f31ee --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/public_call_data.test.ts @@ -0,0 +1,10 @@ +import { makePublicCallData } from '../../tests/factories.js'; +import { PublicCallData } from './public_call_data.js'; + +describe('PublicCallData', () => { + it('PublicCallData after serialization and deserialization is equal to the original', () => { + const original = makePublicCallData(123, true); + const serialized = PublicCallData.fromBuffer(original.toBuffer()); + expect(original).toEqual(serialized); + }); +}); diff --git a/yarn-project/circuits.js/src/structs/kernel/public_call_data.ts b/yarn-project/circuits.js/src/structs/kernel/public_call_data.ts index 5d53b9a49a79..249bd3fa1a88 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_call_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_call_data.ts @@ -1,10 +1,10 @@ -import { type Fr } from '@aztec/foundation/fields'; -import { type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; +import { Fr } from '@aztec/foundation/fields'; +import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; -import { type MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL } from '../../constants.gen.js'; -import { type CallRequest } from '../call_request.js'; -import { type Proof } from '../proof.js'; -import { type PublicCallStackItem } from '../public_call_stack_item.js'; +import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL } from '../../constants.gen.js'; +import { CallRequest } from '../call_request.js'; +import { Proof } from '../proof.js'; +import { PublicCallStackItem } from '../public_call_stack_item.js'; /** * Public calldata assembled from the kernel execution result and proof. @@ -42,4 +42,18 @@ export class PublicCallData { this.bytecodeHash, ); } + + static fromBuffer(buffer: BufferReader | Buffer) { + const reader = BufferReader.asReader(buffer); + return new PublicCallData( + reader.readObject(PublicCallStackItem), + reader.readArray( + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, + CallRequest, + ), + reader.readObject(Proof), + reader.readObject(Fr), + reader.readObject(Fr), + ); + } } diff --git a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.test.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.test.ts new file mode 100644 index 000000000000..0240c1b081cb --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.test.ts @@ -0,0 +1,17 @@ +import { makePublicKernelCircuitPrivateInputs } from '../../tests/factories.js'; +import { PublicKernelCircuitPrivateInputs } from './public_kernel_circuit_private_inputs.js'; + +describe('PublicKernelCircuitPrivateInputs', () => { + it('PublicKernelCircuitPrivateInputs after serialization and deserialization is equal to the original', () => { + const original = makePublicKernelCircuitPrivateInputs(123); + const serialized = PublicKernelCircuitPrivateInputs.fromBuffer(original.toBuffer()); + expect(original).toEqual(serialized); + }); + + it('PublicKernelCircuitPrivateInputs after clone is equal to the original', () => { + const original = makePublicKernelCircuitPrivateInputs(123); + const serialized = original.clone(); + expect(original).toEqual(serialized); + expect(original).not.toBe(serialized); + }); +}); diff --git a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts index 86530dc0f4d9..63f377cd63c0 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_private_inputs.ts @@ -1,7 +1,7 @@ -import { serializeToBuffer } from '@aztec/foundation/serialize'; +import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; -import { type PublicCallData } from './public_call_data.js'; -import { type PublicKernelData } from './public_kernel_data.js'; +import { PublicCallData } from './public_call_data.js'; +import { PublicKernelData } from './public_kernel_data.js'; /** * Inputs to the public kernel circuit. @@ -21,4 +21,15 @@ export class PublicKernelCircuitPrivateInputs { toBuffer() { return serializeToBuffer(this.previousKernel, this.publicCall); } + + static fromBuffer(buffer: BufferReader | Buffer) { + const reader = BufferReader.asReader(buffer); + const previousKernel = reader.readObject(PublicKernelData); + const publicCall = reader.readObject(PublicCallData); + return new PublicKernelCircuitPrivateInputs(previousKernel, publicCall); + } + + clone() { + return PublicKernelCircuitPrivateInputs.fromBuffer(this.toBuffer()); + } } diff --git a/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.test.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.test.ts new file mode 100644 index 000000000000..e53f3f2df214 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.test.ts @@ -0,0 +1,17 @@ +import { makePublicKernelTailCircuitPrivateInputs } from '../../tests/factories.js'; +import { PublicKernelTailCircuitPrivateInputs } from './public_kernel_tail_circuit_private_inputs.js'; + +describe('PublicKernelTailCircuitPrivateInputs', () => { + it('PublicKernelTailCircuitPrivateInputs after serialization and deserialization is equal to the original', () => { + const original = makePublicKernelTailCircuitPrivateInputs(123); + const serialized = PublicKernelTailCircuitPrivateInputs.fromBuffer(original.toBuffer()); + expect(original).toEqual(serialized); + }); + + it('PublicKernelTailCircuitPrivateInputs after clone is equal to the original', () => { + const original = makePublicKernelTailCircuitPrivateInputs(123); + const serialized = original.clone(); + expect(original).toEqual(serialized); + expect(original).not.toBe(serialized); + }); +}); diff --git a/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.ts index 073c0598861d..5399146b7e5c 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel_tail_circuit_private_inputs.ts @@ -1,12 +1,16 @@ -import { serializeToBuffer } from '@aztec/foundation/serialize'; +import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; -import { type NullifierNonExistentReadRequestHints } from '../non_existent_read_request_hints.js'; -import { type NullifierReadRequestHints } from '../read_request_hints.js'; -import { type PublicKernelData } from './public_kernel_data.js'; +import { MAX_PUBLIC_DATA_HINTS } from '../../constants.gen.js'; +import { + type NullifierNonExistentReadRequestHints, + nullifierNonExistentReadRequestHintsFromBuffer, +} from '../non_existent_read_request_hints.js'; +import { PartialStateReference } from '../partial_state_reference.js'; +import { PublicDataHint } from '../public_data_hint.js'; +import { PublicDataReadRequestHints } from '../public_data_read_request_hints.js'; +import { type NullifierReadRequestHints, nullifierReadRequestHintsFromBuffer } from '../read_request_hints.js'; +import { PublicKernelData } from './public_kernel_data.js'; -/** - * Inputs to the public kernel circuit. - */ export class PublicKernelTailCircuitPrivateInputs { constructor( /** @@ -21,6 +25,9 @@ export class PublicKernelTailCircuitPrivateInputs { * Contains hints for the nullifier non existent read requests. */ public readonly nullifierNonExistentReadRequestHints: NullifierNonExistentReadRequestHints, + public readonly publicDataHints: Tuple, + public readonly publicDataReadRequestHints: PublicDataReadRequestHints, + public readonly startState: PartialStateReference, ) {} toBuffer() { @@ -28,6 +35,25 @@ export class PublicKernelTailCircuitPrivateInputs { this.previousKernel, this.nullifierReadRequestHints, this.nullifierNonExistentReadRequestHints, + this.publicDataHints, + this.publicDataReadRequestHints, + this.startState, ); } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new PublicKernelTailCircuitPrivateInputs( + reader.readObject(PublicKernelData), + nullifierReadRequestHintsFromBuffer(reader), + nullifierNonExistentReadRequestHintsFromBuffer(reader), + reader.readArray(MAX_PUBLIC_DATA_HINTS, PublicDataHint), + reader.readObject(PublicDataReadRequestHints), + reader.readObject(PartialStateReference), + ); + } + + clone() { + return PublicKernelTailCircuitPrivateInputs.fromBuffer(this.toBuffer()); + } } diff --git a/yarn-project/circuits.js/src/structs/membership_witness.ts b/yarn-project/circuits.js/src/structs/membership_witness.ts index db0457ef3940..fd623300be17 100644 --- a/yarn-project/circuits.js/src/structs/membership_witness.ts +++ b/yarn-project/circuits.js/src/structs/membership_witness.ts @@ -49,7 +49,7 @@ export class MembershipWitness { * @param leafIndex - Index of the leaf in the Merkle tree. * @returns Membership witness with zero sibling path. */ - public static empty(pathSize: N, leafIndex: bigint): MembershipWitness { + public static empty(pathSize: N, leafIndex = 0n): MembershipWitness { const arr = Array(pathSize) .fill(0) .map(() => Fr.ZERO) as Tuple; diff --git a/yarn-project/circuits.js/src/structs/non_existent_read_request_hints.ts b/yarn-project/circuits.js/src/structs/non_existent_read_request_hints.ts index a459be8be340..faea5129fbb3 100644 --- a/yarn-project/circuits.js/src/structs/non_existent_read_request_hints.ts +++ b/yarn-project/circuits.js/src/structs/non_existent_read_request_hints.ts @@ -18,7 +18,7 @@ export class NonMembershipHint LEAF_PREIMAGE, ) { - return new NonMembershipHint(MembershipWitness.empty(treeHeight, 0n), makeEmptyLeafPreimage()); + return new NonMembershipHint(MembershipWitness.empty(treeHeight), makeEmptyLeafPreimage()); } static fromBuffer( @@ -84,7 +84,12 @@ export class NonExistentReadRequestHints< } toBuffer() { - return serializeToBuffer(this.nonMembershipHints, this.nextPendingValueIndices); + return serializeToBuffer( + this.nonMembershipHints, + this.nextPendingValueIndices, + this.sortedPendingValues, + this.sortedPendingValueHints, + ); } } diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index 95e6dc6715cf..981f7263059c 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -13,6 +13,7 @@ import { type FieldsOf } from '@aztec/foundation/types'; import { GeneratorIndex, + MAX_ENCRYPTED_LOGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, @@ -21,6 +22,7 @@ import { MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, + MAX_UNENCRYPTED_LOGS_PER_CALL, PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, } from '../constants.gen.js'; import { Header } from '../structs/header.js'; @@ -104,12 +106,12 @@ export class PrivateCircuitPublicInputs { * Hash of the encrypted logs emitted in this function call. * Note: Truncated to 31 bytes to fit in Fr. */ - public encryptedLogsHash: Fr, + public encryptedLogsHashes: Tuple, /** * Hash of the unencrypted logs emitted in this function call. * Note: Truncated to 31 bytes to fit in Fr. */ - public unencryptedLogsHash: Fr, + public unencryptedLogsHashes: Tuple, /** * Length of the encrypted log preimages emitted in this function call. * Note: Here so that the gas cost of this request can be measured by circuits, without actually needing to feed @@ -170,8 +172,8 @@ export class PrivateCircuitPublicInputs { reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), reader.readObject(Fr), reader.readObject(Fr), - reader.readObject(Fr), - reader.readObject(Fr), + reader.readArray(MAX_ENCRYPTED_LOGS_PER_CALL, SideEffect), + reader.readArray(MAX_UNENCRYPTED_LOGS_PER_CALL, SideEffect), reader.readObject(Fr), reader.readObject(Fr), reader.readObject(Header), @@ -198,8 +200,8 @@ export class PrivateCircuitPublicInputs { reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), reader.readField(), reader.readField(), - reader.readField(), - reader.readField(), + reader.readArray(MAX_ENCRYPTED_LOGS_PER_CALL, SideEffect), + reader.readArray(MAX_UNENCRYPTED_LOGS_PER_CALL, SideEffect), reader.readField(), reader.readField(), reader.readObject(Header), @@ -229,8 +231,8 @@ export class PrivateCircuitPublicInputs { makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message.empty), Fr.ZERO, Fr.ZERO, - Fr.ZERO, - Fr.ZERO, + makeTuple(MAX_ENCRYPTED_LOGS_PER_CALL, SideEffect.empty), + makeTuple(MAX_UNENCRYPTED_LOGS_PER_CALL, SideEffect.empty), Fr.ZERO, Fr.ZERO, Header.empty(), @@ -258,8 +260,8 @@ export class PrivateCircuitPublicInputs { isZeroArray(this.privateCallStackHashes) && isZeroArray(this.publicCallStackHashes) && isEmptyArray(this.newL2ToL1Msgs) && - this.encryptedLogsHash.isZero() && - this.unencryptedLogsHash.isZero() && + isEmptyArray(this.encryptedLogsHashes) && + isEmptyArray(this.unencryptedLogsHashes) && this.encryptedLogPreimagesLength.isZero() && this.unencryptedLogPreimagesLength.isZero() && this.historicalHeader.isEmpty() && @@ -290,8 +292,8 @@ export class PrivateCircuitPublicInputs { fields.newL2ToL1Msgs, fields.startSideEffectCounter, fields.endSideEffectCounter, - fields.encryptedLogsHash, - fields.unencryptedLogsHash, + fields.encryptedLogsHashes, + fields.unencryptedLogsHashes, fields.encryptedLogPreimagesLength, fields.unencryptedLogPreimagesLength, fields.historicalHeader, diff --git a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts index c294816a6eb1..df93a84cd247 100644 --- a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts @@ -22,11 +22,13 @@ import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, + MAX_UNENCRYPTED_LOGS_PER_CALL, PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH, } from '../constants.gen.js'; import { CallContext } from './call_context.js'; import { ContractStorageRead } from './contract_storage_read.js'; import { ContractStorageUpdateRequest } from './contract_storage_update_request.js'; +import { Gas } from './gas.js'; import { Header } from './header.js'; import { L2ToL1Message } from './l2_to_l1_message.js'; import { ReadRequest } from './read_request.js'; @@ -100,7 +102,7 @@ export class PublicCircuitPublicInputs { * Hash of the unencrypted logs emitted in this function call. * Note: Truncated to 31 bytes to fit in Fr. */ - public unencryptedLogsHash: Fr, + public unencryptedLogsHashes: Tuple, /** * Length of the unencrypted log preimages emitted in this function call. */ @@ -119,6 +121,9 @@ export class PublicCircuitPublicInputs { * Flag indicating if the call was reverted. */ public revertCode: RevertCode, + + /** How much gas was left after execution. */ + public gasLeft: Gas, ) {} /** @@ -149,11 +154,12 @@ export class PublicCircuitPublicInputs { makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message.empty), Fr.ZERO, Fr.ZERO, - Fr.ZERO, + makeTuple(MAX_UNENCRYPTED_LOGS_PER_CALL, SideEffect.empty), Fr.ZERO, Header.empty(), AztecAddress.ZERO, RevertCode.OK, + Gas.empty(), ); } @@ -176,11 +182,12 @@ export class PublicCircuitPublicInputs { isArrayEmpty(this.newL2ToL1Msgs, item => item.isEmpty()) && this.startSideEffectCounter.isZero() && this.endSideEffectCounter.isZero() && - this.unencryptedLogsHash.isZero() && + isArrayEmpty(this.unencryptedLogsHashes, item => item.isEmpty()) && this.unencryptedLogPreimagesLength.isZero() && this.historicalHeader.isEmpty() && this.proverAddress.isZero() && - this.revertCode.isOK() + this.revertCode.isOK() && + this.gasLeft.isEmpty() ); } @@ -204,11 +211,12 @@ export class PublicCircuitPublicInputs { fields.newL2ToL1Msgs, fields.startSideEffectCounter, fields.endSideEffectCounter, - fields.unencryptedLogsHash, + fields.unencryptedLogsHashes, fields.unencryptedLogPreimagesLength, fields.historicalHeader, fields.proverAddress, fields.revertCode, + fields.gasLeft, ] as const; } @@ -251,11 +259,12 @@ export class PublicCircuitPublicInputs { reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), reader.readObject(Fr), reader.readObject(Fr), - reader.readObject(Fr), + reader.readArray(MAX_UNENCRYPTED_LOGS_PER_CALL, SideEffect), reader.readObject(Fr), reader.readObject(Header), reader.readObject(AztecAddress), reader.readObject(RevertCode), + reader.readObject(Gas), ); } @@ -276,11 +285,12 @@ export class PublicCircuitPublicInputs { reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), reader.readField(), reader.readField(), - reader.readField(), + reader.readArray(MAX_UNENCRYPTED_LOGS_PER_CALL, SideEffect), reader.readField(), Header.fromFields(reader), AztecAddress.fromFields(reader), RevertCode.fromFields(reader), + Gas.fromFields(reader), ); } diff --git a/yarn-project/circuits.js/src/structs/public_data_hint.ts b/yarn-project/circuits.js/src/structs/public_data_hint.ts new file mode 100644 index 000000000000..52d73a080f00 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/public_data_hint.ts @@ -0,0 +1,47 @@ +import { Fr } from '@aztec/foundation/fields'; +import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; + +import { PUBLIC_DATA_TREE_HEIGHT } from '../constants.gen.js'; +import { MembershipWitness } from './membership_witness.js'; +import { PublicDataTreeLeafPreimage } from './rollup/public_data_leaf/index.js'; + +export class PublicDataHint { + constructor( + public leafSlot: Fr, + public value: Fr, + public overrideCounter: number, + public membershipWitness: MembershipWitness, + public leafPreimage: PublicDataTreeLeafPreimage, + ) {} + + static empty() { + return new PublicDataHint( + Fr.ZERO, + Fr.ZERO, + 0, + MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT), + PublicDataTreeLeafPreimage.empty(), + ); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new PublicDataHint( + reader.readObject(Fr), + reader.readObject(Fr), + reader.readNumber(), + MembershipWitness.fromBuffer(reader, PUBLIC_DATA_TREE_HEIGHT), + reader.readObject(PublicDataTreeLeafPreimage), + ); + } + + toBuffer() { + return serializeToBuffer( + this.leafSlot, + this.value, + this.overrideCounter, + this.membershipWitness, + this.leafPreimage, + ); + } +} diff --git a/yarn-project/circuits.js/src/structs/public_data_read_request_hints.ts b/yarn-project/circuits.js/src/structs/public_data_read_request_hints.ts new file mode 100644 index 000000000000..8c6b324d63f1 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/public_data_read_request_hints.ts @@ -0,0 +1,86 @@ +import { makeTuple } from '@aztec/foundation/array'; +import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; + +import { MAX_PUBLIC_DATA_READS_PER_TX } from '../constants.gen.js'; +import { PendingReadHint, ReadRequestState, ReadRequestStatus } from './read_request_hints.js'; + +export class LeafDataReadHint { + constructor(public readRequestIndex: number, public dataHintIndex: number) {} + + static nada(readRequestLen: number) { + return new LeafDataReadHint(readRequestLen, 0); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new LeafDataReadHint(reader.readNumber(), reader.readNumber()); + } + + toBuffer() { + return serializeToBuffer(this.readRequestIndex, this.dataHintIndex); + } +} + +export class PublicDataReadRequestHints { + constructor( + public readRequestStatuses: Tuple, + public pendingReadHints: Tuple, + public leafDataReadHints: Tuple, + ) {} + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new PublicDataReadRequestHints( + reader.readArray(MAX_PUBLIC_DATA_READS_PER_TX, ReadRequestStatus), + reader.readArray(MAX_PUBLIC_DATA_READS_PER_TX, PendingReadHint), + reader.readArray(MAX_PUBLIC_DATA_READS_PER_TX, LeafDataReadHint), + ); + } + + toBuffer() { + return serializeToBuffer(this.readRequestStatuses, this.pendingReadHints, this.leafDataReadHints); + } +} + +export class PublicDataReadRequestHintsBuilder { + private hints: PublicDataReadRequestHints; + private numPendingReadHints = 0; + private numLeafDataReadHints = 0; + + constructor() { + this.hints = new PublicDataReadRequestHints( + makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, ReadRequestStatus.nada), + makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PendingReadHint.nada(MAX_PUBLIC_DATA_READS_PER_TX)), + makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => LeafDataReadHint.nada(MAX_PUBLIC_DATA_READS_PER_TX)), + ); + } + + static empty() { + return new PublicDataReadRequestHintsBuilder().toHints(); + } + + addPendingReadRequest(readRequestIndex: number, publicDataWriteIndex: number) { + this.hints.readRequestStatuses[readRequestIndex] = new ReadRequestStatus( + ReadRequestState.PENDING, + this.numPendingReadHints, + ); + this.hints.pendingReadHints[this.numPendingReadHints] = new PendingReadHint(readRequestIndex, publicDataWriteIndex); + this.numPendingReadHints++; + } + + addLeafDataReadRequest(readRequestIndex: number, leafDataDataHintIndex: number) { + this.hints.readRequestStatuses[readRequestIndex] = new ReadRequestStatus( + ReadRequestState.SETTLED, + this.numLeafDataReadHints, + ); + this.hints.leafDataReadHints[this.numLeafDataReadHints] = new LeafDataReadHint( + readRequestIndex, + leafDataDataHintIndex, + ); + this.numLeafDataReadHints++; + } + + toHints() { + return this.hints; + } +} diff --git a/yarn-project/circuits.js/src/structs/read_request_hints.ts b/yarn-project/circuits.js/src/structs/read_request_hints.ts index 6e6439ec426e..fd0be7376148 100644 --- a/yarn-project/circuits.js/src/structs/read_request_hints.ts +++ b/yarn-project/circuits.js/src/structs/read_request_hints.ts @@ -19,6 +19,14 @@ export class ReadRequestStatus { return new ReadRequestStatus(ReadRequestState.NADA, 0); } + static pending(hintIndex: number) { + return new ReadRequestStatus(ReadRequestState.PENDING, hintIndex); + } + + static settled(hintIndex: number) { + return new ReadRequestStatus(ReadRequestState.SETTLED, hintIndex); + } + static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new ReadRequestStatus(reader.readNumber(), reader.readNumber()); @@ -58,7 +66,7 @@ export class SettledReadHint LEAF_PREIMAGE, ) { - return new SettledReadHint(readRequestLen, MembershipWitness.empty(treeHeight, 0n), emptyLeafPreimage()); + return new SettledReadHint(readRequestLen, MembershipWitness.empty(treeHeight), emptyLeafPreimage()); } static fromBuffer( diff --git a/yarn-project/circuits.js/src/structs/tx_request.test.ts b/yarn-project/circuits.js/src/structs/tx_request.test.ts index d353bb36b248..ee364557c5ff 100644 --- a/yarn-project/circuits.js/src/structs/tx_request.test.ts +++ b/yarn-project/circuits.js/src/structs/tx_request.test.ts @@ -7,6 +7,7 @@ import { setupCustomSnapshotSerializers, updateInlineTestData } from '@aztec/fou import { TX_REQUEST_LENGTH } from '../constants.gen.js'; import { makeTxRequest } from '../tests/factories.js'; import { FunctionData } from './function_data.js'; +import { GasSettings } from './gas_settings.js'; import { TxContext } from './tx_context.js'; import { TxRequest } from './tx_request.js'; @@ -36,6 +37,12 @@ describe('TxRequest', () => { functionData: new FunctionData(FunctionSelector.fromField(new Fr(2n)), true), argsHash: new Fr(3), txContext: new TxContext(false, false, Fr.ZERO, Fr.ZERO), + gasSettings: GasSettings.new({ + da: { gasLimit: 2, teardownGasLimit: 1, maxFeePerGas: new Fr(3) }, + l1: { gasLimit: 2, teardownGasLimit: 1, maxFeePerGas: new Fr(3) }, + l2: { gasLimit: 2, teardownGasLimit: 1, maxFeePerGas: new Fr(3) }, + inclusionFee: new Fr(10), + }), }); const hash = txRequest.hash().toString(); diff --git a/yarn-project/circuits.js/src/structs/tx_request.ts b/yarn-project/circuits.js/src/structs/tx_request.ts index 6a3812692a74..8b2337e665d3 100644 --- a/yarn-project/circuits.js/src/structs/tx_request.ts +++ b/yarn-project/circuits.js/src/structs/tx_request.ts @@ -6,6 +6,7 @@ import { type FieldsOf } from '@aztec/foundation/types'; import { GeneratorIndex, TX_REQUEST_LENGTH } from '../constants.gen.js'; import { FunctionData } from './function_data.js'; +import { GasSettings } from './gas_settings.js'; import { TxContext } from './tx_context.js'; /** @@ -13,26 +14,20 @@ import { TxContext } from './tx_context.js'; */ export class TxRequest { constructor( - /** - * Sender. - */ + /** Sender. */ public origin: AztecAddress, - /** - * Function data representing the function to call. - */ + /** Function data representing the function to call. */ public functionData: FunctionData, - /** - * Pedersen hash of function arguments. - */ + /** Pedersen hash of function arguments. */ public argsHash: Fr, - /** - * Transaction context. - */ + /** Transaction context. */ public txContext: TxContext, + /** Gas limits and max fees per dimension. */ + public gasSettings: GasSettings, ) {} static getFields(fields: FieldsOf) { - return [fields.origin, fields.functionData, fields.argsHash, fields.txContext] as const; + return [fields.origin, fields.functionData, fields.argsHash, fields.txContext, fields.gasSettings] as const; } static from(fields: FieldsOf): TxRequest { @@ -67,6 +62,7 @@ export class TxRequest { reader.readObject(FunctionData), Fr.fromBuffer(reader), reader.readObject(TxContext), + reader.readObject(GasSettings), ); } @@ -75,10 +71,16 @@ export class TxRequest { } static empty() { - return new TxRequest(AztecAddress.ZERO, FunctionData.empty(), Fr.zero(), TxContext.empty()); + return new TxRequest(AztecAddress.ZERO, FunctionData.empty(), Fr.zero(), TxContext.empty(), GasSettings.empty()); } isEmpty() { - return this.origin.isZero() && this.functionData.isEmpty() && this.argsHash.isZero() && this.txContext.isEmpty(); + return ( + this.origin.isZero() && + this.functionData.isEmpty() && + this.argsHash.isZero() && + this.txContext.isEmpty() && + this.gasSettings.isEmpty() + ); } } diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index b7a27ac83b25..d6d99d49a5a0 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -1,8 +1,7 @@ -import { makeHalfFullTuple, makeTuple, range } from '@aztec/foundation/array'; +import { type FieldsOf, makeHalfFullTuple, makeTuple, range } from '@aztec/foundation/array'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { EthAddress } from '@aztec/foundation/eth-address'; -import { numToUInt32BE } from '@aztec/foundation/serialize'; import { type ContractClassPublic, type ExecutablePrivateFunctionWithMembershipProof, @@ -39,6 +38,8 @@ import { GrumpkinScalar, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, L2ToL1Message, + MAX_ENCRYPTED_LOGS_PER_CALL, + MAX_ENCRYPTED_LOGS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NOTE_HASHES_PER_CALL, @@ -57,10 +58,13 @@ import { MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_DATA_HINTS, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_CALL, + MAX_UNENCRYPTED_LOGS_PER_TX, MaxBlockNumber, MembershipWitness, MergeRollupInputs, @@ -98,7 +102,9 @@ import { PublicCallRequest, PublicCallStackItem, PublicCircuitPublicInputs, + PublicDataHint, PublicDataRead, + PublicDataReadRequestHintsBuilder, PublicDataTreeLeaf, PublicDataTreeLeafPreimage, PublicDataUpdateRequest, @@ -128,9 +134,9 @@ import { packBytecode, } from '../index.js'; import { ContentCommitment, NUM_BYTES_PER_SHA256 } from '../structs/content_commitment.js'; +import { Gas } from '../structs/gas.js'; import { GasFees } from '../structs/gas_fees.js'; -import { DimensionGasSettings, GasSettings } from '../structs/gas_settings.js'; -import { GasUsed } from '../structs/gas_used.js'; +import { GasSettings } from '../structs/gas_settings.js'; import { GlobalVariables } from '../structs/global_variables.js'; import { Header } from '../structs/header.js'; import { KernelCircuitPublicInputs } from '../structs/kernel/kernel_circuit_public_inputs.js'; @@ -174,20 +180,14 @@ export function makeTxContext(seed: number): TxContext { * @returns A constant data object. */ export function makeConstantData(seed = 1): CombinedConstantData { - return new CombinedConstantData(makeHeader(seed, undefined), makeTxContext(seed + 4), makeGasSettings(seed + 5)); + return new CombinedConstantData(makeHeader(seed, undefined), makeTxContext(seed + 4), makeGasSettings()); } -export function makeGasSettings(seed = 1) { - return new GasSettings( - makeDimensionGasSettings(seed), - makeDimensionGasSettings(seed + 1), - makeDimensionGasSettings(seed + 2), - fr(seed + 3), - ); -} - -export function makeDimensionGasSettings(seed = 1) { - return new DimensionGasSettings(seed, seed + 1, fr(seed + 2)); +/** + * Creates a default instance of gas settings. No seed value is used to ensure we allocate a sensible amount of gas for testing. + */ +export function makeGasSettings() { + return GasSettings.default(); } /** @@ -318,12 +318,12 @@ export function makeCombinedAccumulatedData(seed = 1, full = false): CombinedAcc seed + 0xd00, PublicDataUpdateRequest.empty, ), - makeGasUsed(seed + 0xe00), + makeGas(seed + 0xe00), ); } -export function makeGasUsed(seed = 1) { - return new GasUsed(seed, seed + 1, seed + 2); +export function makeGas(seed = 1) { + return new Gas(seed, seed + 1, seed + 2); } /** @@ -343,8 +343,8 @@ export function makePublicAccumulatedData(seed = 1, full = false): PublicAccumul SideEffectLinkedToNoteHash.empty, ), tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600, Fr.zero), - fr(seed + 0x700), // encrypted logs hash - fr(seed + 0x800), // unencrypted logs hash + tupleGenerator(MAX_ENCRYPTED_LOGS_PER_TX, sideEffectFromNumber, seed + 0x700, SideEffect.empty), // encrypted logs hashes + tupleGenerator(MAX_UNENCRYPTED_LOGS_PER_TX, sideEffectFromNumber, seed + 0x800, SideEffect.empty), // unencrypted logs hashes fr(seed + 0x900), // encrypted_log_preimages_length fr(seed + 0xa00), // unencrypted_log_preimages_length tupleGenerator( @@ -354,7 +354,7 @@ export function makePublicAccumulatedData(seed = 1, full = false): PublicAccumul PublicDataUpdateRequest.empty, ), tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500, CallRequest.empty), - makeGasUsed(seed + 0x600), + makeGas(seed + 0x600), ); } @@ -375,13 +375,13 @@ export function makePrivateAccumulatedData(seed = 1, full = false) { SideEffectLinkedToNoteHash.empty, ), tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600, Fr.zero), - fr(seed + 0x700), // encrypted logs hash - fr(seed + 0x800), // unencrypted logs hash + tupleGenerator(MAX_ENCRYPTED_LOGS_PER_TX, sideEffectFromNumber, seed + 0x700, SideEffect.empty), // encrypted logs hashes + tupleGenerator(MAX_UNENCRYPTED_LOGS_PER_TX, sideEffectFromNumber, seed + 0x800, SideEffect.empty), // unencrypted logs hashes fr(seed + 0x900), // encrypted_log_preimages_length fr(seed + 0xa00), // unencrypted_log_preimages_length tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400, CallRequest.empty), tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500, CallRequest.empty), - makeGasUsed(seed + 0x600), + makeGas(seed + 0x600), ); } @@ -405,18 +405,21 @@ export function makeAggregationObject(seed = 1): AggregationObject { * @param storageContractAddress - The storage contract address set on the call context. * @returns A call context. */ -export function makeCallContext(seed = 0, storageContractAddress = makeAztecAddress(seed + 1)): CallContext { - return new CallContext( - makeAztecAddress(seed), - storageContractAddress, - makeEthAddress(seed + 2), - makeSelector(seed + 3), - false, - false, - 0, - makeGasSettings(seed + 4), - fr(seed + 5), - ); +export function makeCallContext(seed = 0, overrides: Partial> = {}): CallContext { + const gasSettings = makeGasSettings(); + return CallContext.from({ + msgSender: makeAztecAddress(seed), + storageContractAddress: makeAztecAddress(seed + 1), + portalContractAddress: makeEthAddress(seed + 2), + functionSelector: makeSelector(seed + 3), + gasLeft: gasSettings.getLimits(), + isStaticCall: false, + isDelegateCall: false, + sideEffectCounter: 0, + gasSettings, + transactionFee: fr(seed + 6), + ...overrides, + }); } /** @@ -433,7 +436,7 @@ export function makePublicCircuitPublicInputs( const tupleGenerator = full ? makeTuple : makeHalfFullTuple; return new PublicCircuitPublicInputs( - makeCallContext(seed, storageContractAddress), + makeCallContext(seed, { storageContractAddress: storageContractAddress ?? makeAztecAddress(seed) }), fr(seed + 0x100), fr(seed + 0x200), tupleGenerator(MAX_NULLIFIER_READ_REQUESTS_PER_CALL, makeReadRequest, seed + 0x400, ReadRequest.empty), @@ -456,11 +459,12 @@ export function makePublicCircuitPublicInputs( tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, makeL2ToL1Message, seed + 0x900, L2ToL1Message.empty), fr(seed + 0xa00), fr(seed + 0xa01), - fr(seed + 0x901), + tupleGenerator(MAX_UNENCRYPTED_LOGS_PER_CALL, sideEffectFromNumber, seed + 0x901, SideEffect.empty), fr(seed + 0x902), makeHeader(seed + 0xa00, undefined), makeAztecAddress(seed + 0xb01), RevertCode.OK, + makeGas(seed + 0xc00), ); } @@ -540,6 +544,7 @@ export function makeKernelCircuitPublicInputs(seed = 1, fullAccumulatedData = tr makeRollupValidationRequests(seed), makeCombinedAccumulatedData(seed, fullAccumulatedData), makeConstantData(seed + 0x100), + makePartialStateReference(seed + 0x200), RevertCode.OK, ); } @@ -550,18 +555,9 @@ export function makeKernelCircuitPublicInputs(seed = 1, fullAccumulatedData = tr * @returns Public call request. */ export function makePublicCallRequest(seed = 1): PublicCallRequest { - const childCallContext = makeCallContext(seed + 0x2, makeAztecAddress(seed)); - const parentCallContext = CallContext.from({ - msgSender: makeAztecAddress(seed + 0x3), - storageContractAddress: childCallContext.msgSender, - portalContractAddress: makeEthAddress(seed + 2), - functionSelector: makeSelector(seed + 3), - isStaticCall: false, - isDelegateCall: false, - sideEffectCounter: 0, - gasSettings: makeGasSettings(seed + 4), - transactionFee: fr(seed + 5), - }); + const childCallContext = makeCallContext(seed + 0x2, { storageContractAddress: makeAztecAddress(seed) }); + const parentCallContext = makeCallContext(seed + 0x3, { storageContractAddress: childCallContext.msgSender }); + return new PublicCallRequest( makeAztecAddress(seed), new FunctionData(makeSelector(seed + 0x1), false), @@ -803,6 +799,9 @@ export function makePublicKernelTailCircuitPrivateInputs(seed = 1): PublicKernel makePublicKernelData(seed), NullifierReadRequestHintsBuilder.empty(), NullifierNonExistentReadRequestHintsBuilder.empty(), + makeTuple(MAX_PUBLIC_DATA_HINTS, PublicDataHint.empty, seed + 0x100), + PublicDataReadRequestHintsBuilder.empty(), + makePartialStateReference(seed + 0x200), ); } @@ -846,6 +845,7 @@ export function makeTxRequest(seed = 1): TxRequest { functionData: new FunctionData(makeSelector(seed + 0x100), true), argsHash: fr(seed + 0x200), txContext: makeTxContext(seed + 0x400), + gasSettings: makeGasSettings(), }); } @@ -897,17 +897,7 @@ export function makePrivateCallStackItem(seed = 1): PrivateCallStackItem { export function makePrivateCircuitPublicInputs(seed = 0): PrivateCircuitPublicInputs { return PrivateCircuitPublicInputs.from({ maxBlockNumber: new MaxBlockNumber(true, new Fr(seed + 0x31415)), - callContext: new CallContext( - makeAztecAddress(seed + 1), - makeAztecAddress(seed + 2), - new EthAddress(numToUInt32BE(seed + 3, /* eth address is 20 bytes */ 20)), - makeSelector(seed + 4), - true, - true, - 0, - makeGasSettings(seed + 4), - fr(seed + 5), - ), + callContext: makeCallContext(seed, { isDelegateCall: true, isStaticCall: true }), argsHash: fr(seed + 0x100), returnsHash: fr(seed + 0x200), minRevertibleSideEffectCounter: fr(0), @@ -925,8 +915,8 @@ export function makePrivateCircuitPublicInputs(seed = 0): PrivateCircuitPublicIn newL2ToL1Msgs: makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, makeL2ToL1Message, seed + 0x800), startSideEffectCounter: fr(seed + 0x849), endSideEffectCounter: fr(seed + 0x850), - encryptedLogsHash: fr(seed + 0x900), - unencryptedLogsHash: fr(seed + 0xa00), + encryptedLogsHashes: makeTuple(MAX_ENCRYPTED_LOGS_PER_CALL, sideEffectFromNumber, seed + 0x900), + unencryptedLogsHashes: makeTuple(MAX_UNENCRYPTED_LOGS_PER_CALL, sideEffectFromNumber, seed + 0xa00), encryptedLogPreimagesLength: fr(seed + 0xb00), unencryptedLogPreimagesLength: fr(seed + 0xc00), historicalHeader: makeHeader(seed + 0xd00, undefined), diff --git a/yarn-project/circuits.js/src/tests/index.ts b/yarn-project/circuits.js/src/tests/index.ts index 4fa91dd08350..e24620a0a234 100644 --- a/yarn-project/circuits.js/src/tests/index.ts +++ b/yarn-project/circuits.js/src/tests/index.ts @@ -1,2 +1 @@ -export * from './fixtures.js'; export * from './factories.js'; diff --git a/yarn-project/cli/CHANGELOG.md b/yarn-project/cli/CHANGELOG.md index 542908371cc1..bdb8e7a58083 100644 --- a/yarn-project/cli/CHANGELOG.md +++ b/yarn-project/cli/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## [0.35.1](https://github.com/AztecProtocol/aztec-packages/compare/aztec-cli-v0.35.0...aztec-cli-v0.35.1) (2024-04-16) + + +### Miscellaneous + +* **aztec-cli:** Synchronize aztec-packages versions + +## [0.35.0](https://github.com/AztecProtocol/aztec-packages/compare/aztec-cli-v0.34.0...aztec-cli-v0.35.0) (2024-04-16) + + +### ⚠ BREAKING CHANGES + +* pay fee for account init ([#5601](https://github.com/AztecProtocol/aztec-packages/issues/5601)) + +### Features + +* Pay fee for account init ([#5601](https://github.com/AztecProtocol/aztec-packages/issues/5601)) ([aca804f](https://github.com/AztecProtocol/aztec-packages/commit/aca804f96ca9e74b6b553449333e195c0639b151)) + ## [0.34.0](https://github.com/AztecProtocol/aztec-packages/compare/aztec-cli-v0.33.0...aztec-cli-v0.34.0) (2024-04-10) diff --git a/yarn-project/cli/package.json b/yarn-project/cli/package.json index d24e93c8463b..e1a887fb1cb2 100644 --- a/yarn-project/cli/package.json +++ b/yarn-project/cli/package.json @@ -1,6 +1,6 @@ { "name": "@aztec/cli", - "version": "0.34.0", + "version": "0.35.1", "type": "module", "main": "./dest/index.js", "bin": { diff --git a/yarn-project/end-to-end/Earthfile b/yarn-project/end-to-end/Earthfile index 1a77fbc2683f..f75127fe1f2d 100644 --- a/yarn-project/end-to-end/Earthfile +++ b/yarn-project/end-to-end/Earthfile @@ -132,14 +132,16 @@ guides-dapp-testing: # ARG e2e_mode=local # DO +E2E_TEST --test=guides/up_quick_start.test.ts --e2e_mode=$e2e_mode -bench-publish-rollup: - ARG e2e_mode=local - DO +E2E_TEST --test=benchmarks/bench_publish_rollup.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --compose_file=./scripts/docker-compose-no-sandbox.yml +# TODO hanging +# bench-publish-rollup: +# ARG e2e_mode=local +# DO +E2E_TEST --test=benchmarks/bench_publish_rollup.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --compose_file=./scripts/docker-compose-no-sandbox.yml -bench-process-history: - ARG e2e_mode=local - DO +E2E_TEST --test=benchmarks/bench_process_history.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --compose_file=./scripts/docker-compose-no-sandbox.yml +# TODO hanging +# bench-process-history: +# ARG e2e_mode=local +# DO +E2E_TEST --test=benchmarks/bench_process_history.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --compose_file=./scripts/docker-compose-no-sandbox.yml -bench-tx-size: - ARG e2e_mode=local - DO +E2E_TEST --test=benchmarks/bench_tx_size_fees.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --enable_gas=1 --compose_file=./scripts/docker-compose-no-sandbox.yml +# bench-tx-size: +# ARG e2e_mode=local +# DO +E2E_TEST --test=benchmarks/bench_tx_size_fees.test.ts --debug="aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees" --e2e_mode=$e2e_mode --enable_gas=1 --compose_file=./scripts/docker-compose-no-sandbox.yml diff --git a/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts index 493fc8933753..c2bbcc8ceb87 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts @@ -8,6 +8,7 @@ import { PublicFeePaymentMethod, TxStatus, } from '@aztec/aztec.js'; +import { Fr, GasSettings } from '@aztec/circuits.js'; import { FPCContract, GasTokenContract, TokenContract } from '@aztec/noir-contracts.js'; import { getCanonicalGasTokenAddress } from '@aztec/protocol-contracts/gas-token'; @@ -67,16 +68,15 @@ describe('benchmarks/tx_size_fees', () => { () => Promise.resolve(new PrivateFeePaymentMethod(token.address, fpc.address, aliceWallet)), ])('sends a tx with a fee', async createPaymentMethod => { const paymentMethod = await createPaymentMethod(); + const gasSettings = GasSettings.new({ + da: { gasLimit: 5, teardownGasLimit: 3, maxFeePerGas: Fr.ONE }, + l1: { gasLimit: 5, teardownGasLimit: 3, maxFeePerGas: Fr.ONE }, + l2: { gasLimit: 5, teardownGasLimit: 3, maxFeePerGas: Fr.ONE }, + inclusionFee: new Fr(6), + }); const tx = await token.methods .transfer(aliceWallet.getAddress(), bobAddress, 1n, 0) - .send({ - fee: paymentMethod - ? { - maxFee: 3n, - paymentMethod, - } - : undefined, - }) + .send({ fee: paymentMethod ? { gasSettings, paymentMethod } : undefined }) .wait(); expect(tx.status).toEqual(TxStatus.MINED); diff --git a/yarn-project/end-to-end/src/composed/cli_docs_sandbox.test.ts b/yarn-project/end-to-end/src/composed/cli_docs_sandbox.test.ts index 3b0a8e20400c..446330a461e0 100644 --- a/yarn-project/end-to-end/src/composed/cli_docs_sandbox.test.ts +++ b/yarn-project/end-to-end/src/composed/cli_docs_sandbox.test.ts @@ -117,6 +117,7 @@ FPCContractArtifact GasTokenContractArtifact ImportTestContractArtifact InclusionProofsContractArtifact +KeyRegistryContractArtifact LendingContractArtifact MultiCallEntrypointContractArtifact ParentContractArtifact diff --git a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts index 3de9f8a1b0b8..1a941a6f6850 100644 --- a/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts +++ b/yarn-project/end-to-end/src/e2e_avm_simulator.test.ts @@ -80,15 +80,15 @@ describe('e2e_avm_simulator', () => { }, 50_000); it('Can execute ACVM function among AVM functions', async () => { - expect(await avmContract.methods.constant_field_acvm().simulate()).toEqual([123456n]); + expect(await avmContract.methods.constant_field_acvm().simulate()).toEqual(123456n); }); it('Can call AVM function from ACVM', async () => { - expect(await avmContract.methods.call_avm_from_acvm().simulate()).toEqual([123456n]); + expect(await avmContract.methods.call_avm_from_acvm().simulate()).toEqual(123456n); }); it('Can call ACVM function from AVM', async () => { - expect(await avmContract.methods.call_acvm_from_avm().simulate()).toEqual([123456n]); + expect(await avmContract.methods.call_acvm_from_avm().simulate()).toEqual(123456n); }); it('AVM sees settled nullifiers by ACVM', async () => { @@ -146,7 +146,7 @@ describe('e2e_avm_simulator', () => { describe('Storage', () => { it('Read immutable (initialized) storage (Field)', async () => { - expect(await avmContract.methods.read_storage_immutable().simulate()).toEqual([42n]); + expect(await avmContract.methods.read_storage_immutable().simulate()).toEqual(42n); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts index e7d3b42101fd..862c4a1ac097 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts @@ -245,11 +245,16 @@ describe('e2e_cross_chain_messaging', () => { secretHashForL2MessageConsumption, ); + // get message leaf index, needed for claiming in public + const maybeIndexAndPath = await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash, 0n); + expect(maybeIndexAndPath).toBeDefined(); + const messageLeafIndex = maybeIndexAndPath![0]; + // 3. Consume L1 -> L2 message and try to mint publicly on L2 - should fail await expect( l2Bridge .withWallet(user2Wallet) - .methods.claim_public(ownerAddress, bridgeAmount, secretForL2MessageConsumption) + .methods.claim_public(ownerAddress, bridgeAmount, secretForL2MessageConsumption, messageLeafIndex) .prove(), ).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`); }, 120_000); diff --git a/yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts b/yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts index 93095f383b8b..a5398f9506b4 100644 --- a/yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts +++ b/yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts @@ -11,6 +11,7 @@ import { PublicFeePaymentMethod, SentTx, } from '@aztec/aztec.js'; +import { GasSettings } from '@aztec/circuits.js'; import { DefaultDappEntrypoint } from '@aztec/entrypoints/dapp'; import { AppSubscriptionContract, @@ -52,13 +53,22 @@ describe('e2e_dapp_subscription', () => { const PRIVATELY_MINTED_BANANAS = 600n; const FEE_AMOUNT = 1n; - const REFUND = 2n; // intentionally overpay the gas fee. This is the expected refund. + const REFUND = 29n; // intentionally overpay the gas fee. This is the expected refund. const MAX_FEE = FEE_AMOUNT + REFUND; + const GAS_SETTINGS = GasSettings.new({ + da: { gasLimit: 5, teardownGasLimit: 3, maxFeePerGas: Fr.ONE }, + l1: { gasLimit: 5, teardownGasLimit: 3, maxFeePerGas: Fr.ONE }, + l2: { gasLimit: 5, teardownGasLimit: 3, maxFeePerGas: Fr.ONE }, + inclusionFee: new Fr(6), + }); + beforeAll(async () => { process.env.PXE_URL = ''; process.env.ENABLE_GAS ??= '1'; + expect(GAS_SETTINGS.getFeeLimit().toBigInt()).toEqual(MAX_FEE); + let wallets: AccountWalletWithPrivateKey[]; let aztecNode: AztecNode; let deployL1ContractsValues: DeployL1Contracts; @@ -219,7 +229,7 @@ describe('e2e_dapp_subscription', () => { // subscribe again. This will overwrite the subscription await subscribe(new PrivateFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet), MAX_FEE, 0); await expect(dappIncrement()).rejects.toThrow( - "Failed to solve brillig function, reason: explicit trap hit in brillig '(context.block_number()) as u64 < expiry_block_number as u64'", + "Failed to solve brillig function '(context.block_number()) as u64 < expiry_block_number as u64'", ); }); @@ -243,12 +253,7 @@ describe('e2e_dapp_subscription', () => { return subscriptionContract .withWallet(aliceWallet) .methods.subscribe(aliceAddress, nonce, (await pxe.getBlockNumber()) + blockDelta, txCount) - .send({ - fee: { - maxFee, - paymentMethod, - }, - }) + .send({ fee: { gasSettings: GAS_SETTINGS, paymentMethod } }) .wait(); } diff --git a/yarn-project/end-to-end/src/e2e_delegate_calls.test.ts b/yarn-project/end-to-end/src/e2e_delegate_calls/delegate.test.ts similarity index 54% rename from yarn-project/end-to-end/src/e2e_delegate_calls.test.ts rename to yarn-project/end-to-end/src/e2e_delegate_calls/delegate.test.ts index 45fb4a22e1d1..03246dcff0fd 100644 --- a/yarn-project/end-to-end/src/e2e_delegate_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_delegate_calls/delegate.test.ts @@ -1,34 +1,25 @@ -import { type Wallet } from '@aztec/aztec.js'; -import { DelegatedOnContract, DelegatorContract } from '@aztec/noir-contracts.js'; - -import { setup } from './fixtures/utils.js'; +import { DelegateCallsTest } from './delegate_calls_test.js'; describe('e2e_delegate_calls', () => { - let wallet: Wallet; - let delegatorContract: DelegatorContract; - let delegatedOnContract: DelegatedOnContract; - let teardown: () => Promise; - - beforeEach(async () => { - ({ teardown, wallet } = await setup()); - }, 100_000); - - afterEach(() => teardown()); + const t = new DelegateCallsTest('delegate_calls'); + let { delegatorContract, delegatedOnContract, wallet } = t; + + beforeAll(async () => { + await t.applyBaseSnapshots(); + await t.setup(); + // Have to destructure again to ensure we have latest refs. + ({ delegatorContract, delegatedOnContract, wallet } = t); + }); - beforeEach(async () => { - delegatorContract = await DelegatorContract.deploy(wallet).send().deployed(); - delegatedOnContract = await DelegatedOnContract.deploy(wallet).send().deployed(); - }, 100_000); + afterAll(async () => { + await t.teardown(); + }); describe('delegates on another contract', () => { it("runs another contract's private function on delegator's storage", async () => { const sentValue = 42n; await delegatorContract.methods - .private_delegate_set_value( - delegatedOnContract.address, - delegatedOnContract.methods.private_set_value.selector, - [sentValue, wallet.getCompleteAddress().address], - ) + .private_delegate_set_value(delegatedOnContract.address, sentValue, wallet.getCompleteAddress().address) .send() .wait(); @@ -46,14 +37,7 @@ describe('e2e_delegate_calls', () => { it("runs another contract's enqueued public function on delegator's storage", async () => { const sentValue = 42n; - await delegatorContract.methods - .enqueued_delegate_set_value( - delegatedOnContract.address, - delegatedOnContract.methods.public_set_value.selector, - [sentValue], - ) - .send() - .wait(); + await delegatorContract.methods.enqueued_delegate_set_value(delegatedOnContract.address, sentValue).send().wait(); const delegatorValue = await delegatorContract.methods.view_public_value().simulate(); const delegatedOnValue = await delegatedOnContract.methods.view_public_value().simulate(); @@ -64,12 +48,7 @@ describe('e2e_delegate_calls', () => { it("runs another contract's public function on delegator's storage", async () => { const sentValue = 42n; - await delegatorContract.methods - .public_delegate_set_value(delegatedOnContract.address, delegatedOnContract.methods.public_set_value.selector, [ - sentValue, - ]) - .send() - .wait(); + await delegatorContract.methods.public_delegate_set_value(delegatedOnContract.address, sentValue).send().wait(); const delegatorValue = await delegatorContract.methods.view_public_value().simulate(); const delegatedOnValue = await delegatedOnContract.methods.view_public_value().simulate(); diff --git a/yarn-project/end-to-end/src/e2e_delegate_calls/delegate_calls_test.ts b/yarn-project/end-to-end/src/e2e_delegate_calls/delegate_calls_test.ts new file mode 100644 index 000000000000..457408a05f7a --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_delegate_calls/delegate_calls_test.ts @@ -0,0 +1,72 @@ +import { getSchnorrAccount } from '@aztec/accounts/schnorr'; +import { type AccountWallet, type DebugLogger, createDebugLogger } from '@aztec/aztec.js'; +import { DelegatedOnContract, DelegatorContract } from '@aztec/noir-contracts.js'; + +import { SnapshotManager, type SubsystemsContext, addAccounts } from '../fixtures/snapshot_manager.js'; + +const { E2E_DATA_PATH: dataPath } = process.env; + +export class DelegateCallsTest { + private snapshotManager: SnapshotManager; + logger: DebugLogger; + wallet!: AccountWallet; + delegatorContract!: DelegatorContract; + delegatedOnContract!: DelegatedOnContract; + + constructor(testName: string) { + this.logger = createDebugLogger(`aztec:e2e_delegate_calls:${testName}`); + this.snapshotManager = new SnapshotManager(`e2e_delegate_calls/${testName}`, dataPath); + } + + /** + * Adds two state shifts to snapshot manager. + * 1. Add 3 accounts. + * 2. Publicly deploy accounts, deploy token contract and a "bad account". + */ + async applyBaseSnapshots() { + await this.snapshotManager.snapshot('accounts', addAccounts(1, this.logger), async ({ accountKeys }, { pxe }) => { + const accountManager = getSchnorrAccount(pxe, accountKeys[0][0], accountKeys[0][1], 1); + this.wallet = await accountManager.getWallet(); + this.logger.verbose(`Wallet address: ${this.wallet.getAddress()}`); + }); + + await this.snapshotManager.snapshot( + 'e2e_delegate_calls', + async () => { + this.logger.verbose(`Deploying DelegatorContract...`); + this.delegatorContract = await DelegatorContract.deploy(this.wallet).send().deployed(); + this.logger.verbose(`Delegator deployed to ${this.delegatorContract.address}`); + + this.logger.verbose(`Deploying DelegatedOnContract...`); + this.delegatedOnContract = await DelegatedOnContract.deploy(this.wallet).send().deployed(); + + return { + delegatorContractAddress: this.delegatorContract.address, + delegatedOnContractAddress: this.delegatedOnContract.address, + }; + }, + async ({ delegatorContractAddress, delegatedOnContractAddress }) => { + // Restore the token contract state. + this.delegatorContract = await DelegatorContract.at(delegatorContractAddress, this.wallet); + this.logger.verbose(`Delegator contract address: ${this.delegatorContract.address}`); + + this.delegatedOnContract = await DelegatedOnContract.at(delegatedOnContractAddress, this.wallet); + this.logger.verbose(`DelegatedOn address: ${this.delegatedOnContract.address}`); + }, + ); + } + + async setup() { + await this.snapshotManager.setup(); + } + + snapshot = ( + name: string, + apply: (context: SubsystemsContext) => Promise, + restore: (snapshotData: T, context: SubsystemsContext) => Promise = () => Promise.resolve(), + ): Promise => this.snapshotManager.snapshot(name, apply, restore); + + async teardown() { + await this.snapshotManager.teardown(); + } +} diff --git a/yarn-project/end-to-end/src/e2e_fees.test.ts b/yarn-project/end-to-end/src/e2e_fees.test.ts index 010b5a0da443..d6301790f781 100644 --- a/yarn-project/end-to-end/src/e2e_fees.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees.test.ts @@ -16,7 +16,7 @@ import { computeAuthWitMessageHash, computeMessageSecretHash, } from '@aztec/aztec.js'; -import { FunctionData } from '@aztec/circuits.js'; +import { FunctionData, GasSettings } from '@aztec/circuits.js'; import { type ContractArtifact, decodeFunctionSignature } from '@aztec/foundation/abi'; import { TokenContract as BananaCoin, @@ -46,6 +46,7 @@ describe('e2e_fees', () => { let gasTokenContract: GasTokenContract; let bananaCoin: BananaCoin; let bananaFPC: FPCContract; + let logger: DebugLogger; let gasBridgeTestHarness: IGasBridgingTestHarness; @@ -53,9 +54,17 @@ describe('e2e_fees', () => { let bananaPublicBalances: BalancesFn; let bananaPrivateBalances: BalancesFn; + const gasSettings = GasSettings.new({ + da: { gasLimit: 5, teardownGasLimit: 3, maxFeePerGas: Fr.ONE }, + l1: { gasLimit: 5, teardownGasLimit: 3, maxFeePerGas: Fr.ONE }, + l2: { gasLimit: 5, teardownGasLimit: 3, maxFeePerGas: Fr.ONE }, + inclusionFee: new Fr(6), + }); + beforeAll(async () => { - const { wallets: _wallets, aztecNode, deployL1ContractsValues, logger, pxe } = await setup(3, {}, {}, true); - wallets = _wallets; + const ctx = await setup(3, {}, {}, true); + const { aztecNode, deployL1ContractsValues, pxe } = ctx; + ({ wallets, logger } = ctx); logFunctionSignatures(BananaCoin.artifact, logger); logFunctionSignatures(FPCContract.artifact, logger); @@ -72,6 +81,7 @@ describe('e2e_fees', () => { sequencerAddress = wallets[2].getAddress(); gasBridgeTestHarness = await GasPortalTestingHarnessFactory.create({ + aztecNode: aztecNode, pxeService: pxe, publicClient: deployL1ContractsValues.publicClient, walletClient: deployL1ContractsValues.walletClient, @@ -106,8 +116,6 @@ describe('e2e_fees', () => { const OutrageousPublicAmountAliceDoesNotHave = 10000n; const PublicMintedAlicePublicBananas = 1000n; const FeeAmount = 1n; - const RefundAmount = 2n; - const MaxFee = FeeAmount + RefundAmount; const [initialAlicePrivateBananas, initialFPCPrivateBananas] = await bananaPrivateBalances( aliceAddress, @@ -130,7 +138,7 @@ describe('e2e_fees', () => { .transfer_public(aliceAddress, sequencerAddress, OutrageousPublicAmountAliceDoesNotHave, 0) .send({ fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, wallets[0]), }, }) @@ -160,7 +168,7 @@ describe('e2e_fees', () => { .send({ skipPublicSimulation: true, fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, wallets[0]), }, }) @@ -194,6 +202,8 @@ describe('e2e_fees', () => { let InitialAliceGas: bigint; let InitialBobPrivateBananas: bigint; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + let InitialBobPublicBananas: bigint; let InitialFPCPrivateBananas: bigint; let InitialFPCPublicBananas: bigint; @@ -207,23 +217,26 @@ describe('e2e_fees', () => { let RefundSecret: Fr; beforeAll(async () => { - // fund Alice - await mintPrivate(100n, aliceAddress); + // Fund Alice private and publicly + await mintPrivate(1000n, aliceAddress); + await bananaCoin.methods.mint_public(aliceAddress, 1000n).send().wait(); }); beforeEach(async () => { FeeAmount = 1n; - RefundAmount = 2n; - MaxFee = FeeAmount + RefundAmount; + MaxFee = 30n; + RefundAmount = MaxFee - FeeAmount; RefundSecret = Fr.random(); + expect(gasSettings.getFeeLimit().toBigInt()).toEqual(MaxFee); + [ [InitialAlicePrivateBananas, InitialBobPrivateBananas, InitialFPCPrivateBananas], - [InitialAlicePublicBananas, InitialFPCPublicBananas], + [InitialAlicePublicBananas, InitialBobPublicBananas, InitialFPCPublicBananas], [InitialAliceGas, InitialFPCGas, InitialSequencerGas], ] = await Promise.all([ bananaPrivateBalances(aliceAddress, bobAddress, bananaFPC.address), - bananaPublicBalances(aliceAddress, bananaFPC.address), + bananaPublicBalances(aliceAddress, bobAddress, bananaFPC.address), gasBalances(aliceAddress, bananaFPC.address, sequencerAddress), ]); }); @@ -261,7 +274,7 @@ describe('e2e_fees', () => { .transfer(aliceAddress, bobAddress, transferAmount, 0n) .send({ fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new PrivateFeePaymentMethod( bananaCoin.address, bananaFPC.address, @@ -324,7 +337,7 @@ describe('e2e_fees', () => { .privately_mint_private_note(newlyMintedBananas) .send({ fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new PrivateFeePaymentMethod( bananaCoin.address, bananaFPC.address, @@ -390,7 +403,7 @@ describe('e2e_fees', () => { .shield(aliceAddress, shieldedBananas, shieldSecretHash, 0n) .send({ fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new PrivateFeePaymentMethod( bananaCoin.address, bananaFPC.address, @@ -462,7 +475,7 @@ describe('e2e_fees', () => { ]) .send({ fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new PrivateFeePaymentMethod( bananaCoin.address, bananaFPC.address, @@ -516,7 +529,7 @@ describe('e2e_fees', () => { // we need to skip public simulation otherwise the PXE refuses to accept the TX skipPublicSimulation: true, fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new PrivateFeePaymentMethod( bananaCoin.address, bankruptFPC.address, @@ -532,10 +545,6 @@ describe('e2e_fees', () => { it('fails transaction that error in setup', async () => { const OutrageousPublicAmountAliceDoesNotHave = 10000n; - // const PublicMintedAlicePublicBananas = 1000n; - const FeeAmount = 1n; - const RefundAmount = 2n; - const MaxFee = FeeAmount + RefundAmount; // simulation throws an error when setup fails await expect( @@ -543,7 +552,7 @@ describe('e2e_fees', () => { .transfer_public(aliceAddress, sequencerAddress, OutrageousPublicAmountAliceDoesNotHave, 0) .send({ fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new BuggedSetupFeePaymentMethod(bananaCoin.address, bananaFPC.address, wallets[0]), }, }) @@ -557,7 +566,7 @@ describe('e2e_fees', () => { .send({ skipPublicSimulation: true, fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new BuggedSetupFeePaymentMethod(bananaCoin.address, bananaFPC.address, wallets[0]), }, }) @@ -570,11 +579,7 @@ describe('e2e_fees', () => { * We trigger an error in teardown by having the FPC authorize a transfer of its entire balance to Alice * as part of app logic. This will cause the FPC to not have enough funds to pay the refund back to Alice. */ - const PublicMintedAlicePublicBananas = 1000n; - const FeeAmount = 1n; - const RefundAmount = 2n; - const MaxFee = FeeAmount + RefundAmount; const [initialAlicePrivateBananas, initialFPCPrivateBananas] = await bananaPrivateBalances( aliceAddress, @@ -597,7 +602,7 @@ describe('e2e_fees', () => { .mint_public(aliceAddress, 1n) // random operation .send({ fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new BuggedTeardownFeePaymentMethod(bananaCoin.address, bananaFPC.address, wallets[0]), }, }) @@ -611,7 +616,7 @@ describe('e2e_fees', () => { .send({ skipPublicSimulation: true, fee: { - maxFee: MaxFee, + gasSettings, paymentMethod: new BuggedTeardownFeePaymentMethod(bananaCoin.address, bananaFPC.address, wallets[0]), }, }) @@ -672,7 +677,8 @@ describe('e2e_fees', () => { }); class BuggedSetupFeePaymentMethod extends PublicFeePaymentMethod { - getFunctionCalls(maxFee: Fr): Promise { + override getFunctionCalls(gasSettings: GasSettings): Promise { + const maxFee = gasSettings.getFeeLimit(); const nonce = Fr.random(); const messageHash = computeAuthWitMessageHash( this.paymentContract, @@ -705,9 +711,10 @@ class BuggedSetupFeePaymentMethod extends PublicFeePaymentMethod { } class BuggedTeardownFeePaymentMethod extends PublicFeePaymentMethod { - async getFunctionCalls(maxFee: Fr): Promise { + override async getFunctionCalls(gasSettings: GasSettings): Promise { // authorize the FPC to take the max fee from Alice const nonce = Fr.random(); + const maxFee = gasSettings.getFeeLimit(); const messageHash1 = computeAuthWitMessageHash( this.paymentContract, this.wallet.getChainId(), diff --git a/yarn-project/end-to-end/src/e2e_key_registry.test.ts b/yarn-project/end-to-end/src/e2e_key_registry.test.ts new file mode 100644 index 000000000000..37f6ac8cea5b --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_key_registry.test.ts @@ -0,0 +1,261 @@ +import { type AccountWallet, AztecAddress, Fr, type PXE } from '@aztec/aztec.js'; +import { GeneratorIndex } from '@aztec/circuits.js'; +import { poseidon2Hash } from '@aztec/foundation/crypto'; +import { KeyRegistryContract, TestContract } from '@aztec/noir-contracts.js'; + +import { jest } from '@jest/globals'; + +import { publicDeployAccounts, setup } from './fixtures/utils.js'; + +const TIMEOUT = 100_000; + +describe('SharedMutablePrivateGetter', () => { + let keyRegistry: KeyRegistryContract; + let testContract: TestContract; + let pxe: PXE; + jest.setTimeout(TIMEOUT); + + let wallets: AccountWallet[]; + + let teardown: () => Promise; + + beforeAll(async () => { + ({ teardown, pxe, wallets } = await setup(2)); + testContract = await TestContract.deploy(wallets[0]).send().deployed(); + keyRegistry = await KeyRegistryContract.deploy(wallets[0]).send().deployed(); + + await publicDeployAccounts(wallets[0], wallets.slice(0, 2)); + }, 120_000); + + const delay = async (blocks: number) => { + for (let i = 0; i < blocks; i++) { + await testContract.methods.delay().send().wait(); + } + }; + + afterAll(() => teardown()); + + describe('failure cases', () => { + let accountAddedToRegistry: AztecAddress; + + describe('should fail registering with bad input', () => { + const partialAddress = new Fr(69); + + const masterNullifierPublicKey = new Fr(12); + const masterIncomingViewingPublicKey = new Fr(34); + const masterOutgoingViewingPublicKey = new Fr(56); + const masterTaggingPublicKey = new Fr(78); + + // TODO(#5726): use computePublicKeysHash function + const publicKeysHash = poseidon2Hash([ + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + GeneratorIndex.PUBLIC_KEYS_HASH, + ]); + + // We hash the partial address and the public keys hash to get the account address + // TODO(#5726): Move the following line to AztecAddress class? + accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + + it('should fail registering with mismatched address', async () => { + const mismatchedAddress = Fr.random(); + + await expect( + keyRegistry + .withWallet(wallets[0]) + .methods.register( + AztecAddress.fromField(mismatchedAddress), + partialAddress, + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ) + .send() + .wait(), + ).rejects.toThrow('Computed address does not match supplied address'); + }); + + it('should fail registering with mismatched nullifier public key', async () => { + const mismatchedMasterNullifierPublicKey = Fr.random(); + + await expect( + keyRegistry + .withWallet(wallets[0]) + .methods.register( + AztecAddress.fromField(accountAddedToRegistry), + partialAddress, + mismatchedMasterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ) + .send() + .wait(), + ).rejects.toThrow('Computed address does not match supplied address'); + }); + }); + + describe('should fail when rotating keys with bad input', () => { + it('should fail when trying to rotate setting a 0 key', async () => { + await expect( + keyRegistry + .withWallet(wallets[0]) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), new Fr(0)) + .send() + .wait(), + ).rejects.toThrow('New nullifier public key must be non-zero'); + }); + + it('should fail when trying to rotate for another address without authwit', async () => { + await expect( + keyRegistry + .withWallet(wallets[0]) + .methods.rotate_nullifier_public_key(wallets[1].getAddress(), new Fr(2)) + .send() + .wait(), + ).rejects.toThrow('Assertion failed: Message not authorized by account'); + }); + }); + }); + + describe('key registration flow', () => { + let accountAddedToRegistry: AztecAddress; + + it('should generate and register with original keys', async () => { + const partialAddress = new Fr(69); + + const masterNullifierPublicKey = new Fr(12); + const masterIncomingViewingPublicKey = new Fr(34); + const masterOutgoingViewingPublicKey = new Fr(56); + const masterTaggingPublicKey = new Fr(78); + + const publicKeysHash = poseidon2Hash([ + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + GeneratorIndex.PUBLIC_KEYS_HASH, + ]); + + // We hash the partial address and the public keys hash to get the account address + // TODO(#5726): Move the following line to AztecAddress class? + accountAddedToRegistry = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]); + + await keyRegistry + .withWallet(wallets[0]) + .methods.register( + AztecAddress.fromField(accountAddedToRegistry), + partialAddress, + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ) + .send() + .wait(); + }); + + it('checks our registry contract from test contract and fails because the address has not been registered yet', async () => { + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(Fr.ZERO); + }); + + it('checks our registry contract from test contract and finds the address and associated nullifier public key after a delay', async () => { + await delay(5); + + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, accountAddedToRegistry) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(12)); + }); + }); + + describe('key rotation flow', () => { + it('we rotate the nullifier key', async () => { + // This changes + const newMasterNullifierPublicKey = new Fr(910); + + await keyRegistry + .withWallet(wallets[0]) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey) + .send() + .wait(); + }); + + it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); + }); + + it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + await delay(5); + + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); + }); + }); + + describe('key rotation flow with authwit', () => { + it('wallet 0 lets wallet 1 call rotate_nullifier_public_key on his behalf with a pre-defined new public key', async () => { + // This changes + const newMasterNullifierPublicKey = new Fr(420); + + const action = keyRegistry + .withWallet(wallets[1]) + .methods.rotate_nullifier_public_key(wallets[0].getAddress(), newMasterNullifierPublicKey); + + await wallets[0] + .setPublicAuthWit({ caller: wallets[1].getCompleteAddress().address, action }, true) + .send() + .wait(); + + await action.send().wait(); + }); + + it("checks our registry contract from test contract and finds our old public key because the key rotation hasn't been applied yet", async () => { + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(910)); + }); + + it('checks our registry contract from test contract and finds the new nullifier public key that has been rotated', async () => { + await delay(5); + + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter_for_registry_contract(keyRegistry.address, 1, wallets[0].getAddress()) + .send() + .wait(); + + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(420)); + }); + }); +}); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts index 102e10069d30..661978ce75ce 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts @@ -1,9 +1,6 @@ import { type AztecAddress, BatchCall, type DebugLogger, Fr, type PXE, type Wallet, toBigIntBE } from '@aztec/aztec.js'; -import { getTestData, isGenerateTestDataEnabled } from '@aztec/foundation/testing'; import { ChildContract, ImportTestContract, ParentContract, TestContract } from '@aztec/noir-contracts.js'; -import { writeFileSync } from 'fs'; - import { setup } from './fixtures/utils.js'; describe('e2e_nested_contract', () => { @@ -34,35 +31,6 @@ describe('e2e_nested_contract', () => { .entry_point(childContract.address, childContract.methods.value.selector) .send() .wait(); - - if (isGenerateTestDataEnabled()) { - { - const privateKernelInputsInit = getTestData('private-kernel-inputs-init'); - const nestedCallPrivateKernelInput = privateKernelInputsInit[0]; - writeFileSync( - '../noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-init.hex', - nestedCallPrivateKernelInput.toBuffer().toString('hex'), - ); - } - - { - const privateKernelInputsInner = getTestData('private-kernel-inputs-inner'); - const nestedCallPrivateKernelInput = privateKernelInputsInner[privateKernelInputsInner.length - 1]; - writeFileSync( - '../noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-inner.hex', - nestedCallPrivateKernelInput.toBuffer().toString('hex'), - ); - } - - { - const privateKernelInputsOrdering = getTestData('private-kernel-inputs-ordering'); - const nestedCallPrivateKernelInput = privateKernelInputsOrdering[0]; - writeFileSync( - '../noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-ordering.hex', - nestedCallPrivateKernelInput.toBuffer().toString('hex'), - ); - } - } }, 100_000); it('fails simulation if calling a function not allowed to be called externally', async () => { @@ -169,7 +137,7 @@ describe('e2e_nested_contract', () => { it('calls a method with multiple arguments', async () => { logger.info(`Calling main on importer contract`); - await importerContract.methods.main(testContract.address).send().wait(); + await importerContract.methods.main_contract(testContract.address).send().wait(); }, 30_000); it('calls a method no arguments', async () => { diff --git a/yarn-project/end-to-end/src/e2e_note_getter.test.ts b/yarn-project/end-to-end/src/e2e_note_getter.test.ts index 27e6be2c03af..54a2084be588 100644 --- a/yarn-project/end-to-end/src/e2e_note_getter.test.ts +++ b/yarn-project/end-to-end/src/e2e_note_getter.test.ts @@ -41,10 +41,11 @@ describe('e2e_note_getter', () => { // await Promise.all(numbers.map(number => contract.methods.insert_note(number).send().wait())); // It causes a race condition complaining about root mismatch - await contract.methods - .insert_notes([...Array(10).keys()]) - .send() - .wait(); + // Note: Separated the below into calls of 3 to avoid reaching logs per call limit + await contract.methods.insert_notes([0, 1, 2]).send().wait(); + await contract.methods.insert_notes([3, 4, 5]).send().wait(); + await contract.methods.insert_notes([6, 7, 8]).send().wait(); + await contract.methods.insert_note(9, new Fr(1n)).send().wait(); await contract.methods.insert_note(5, Fr.ZERO).send().wait(); const [returnEq, returnNeq, returnLt, returnGt, returnLte, returnGte] = await Promise.all([ diff --git a/yarn-project/end-to-end/src/e2e_ordering.test.ts b/yarn-project/end-to-end/src/e2e_ordering.test.ts index e05f09b1d21a..16ce4309f7dd 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -109,16 +109,19 @@ describe('e2e_ordering', () => { // Emitting logs twice (first in a nested call, then directly) leads // to a misordering of them by the public kernel because it sees them // in reverse order. More info in this thread: https://discourse.aztec.network/t/identifying-the-ordering-of-state-access-across-contract-calls/382/12#transition-counters-for-private-calls-2 - // Once fixed, re-include the `set_value_twice_with_nested_first` test - //it.each(['set_value_twice_with_nested_first', 'set_value_twice_with_nested_last'] as const)( - it.each(['set_value_twice_with_nested_last'] as const)('orders unencrypted logs in %s', async method => { - const expectedOrder = expectedOrders[method]; + // The below only works due to a hack which sorts the logs in ts + // See tail_phase_manager.ts + it.each(['set_value_twice_with_nested_first', 'set_value_twice_with_nested_last'] as const)( + 'orders unencrypted logs in %s', + async method => { + const expectedOrder = expectedOrders[method]; - await child.methods[method]().send().wait(); + await child.methods[method]().send().wait(); - // Logs are emitted in the expected order - await expectLogsFromLastBlockToBe(expectedOrder); - }); + // Logs are emitted in the expected order + await expectLogsFromLastBlockToBe(expectedOrder); + }, + ); }); }); }); diff --git a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts index b26721bd6724..e8aa0bacee3c 100644 --- a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts @@ -5,6 +5,8 @@ import { type DebugLogger, type DeployL1Contracts, EthAddress, + type EthAddressLike, + type FieldLike, Fr, L1Actor, L1ToL2Message, @@ -92,8 +94,13 @@ describe('e2e_public_cross_chain_messaging', () => { // Wait for the message to be available for consumption await crossChainTestHarness.makeMessageConsumable(msgHash); + // Get message leaf index, needed for claiming in public + const maybeIndexAndPath = await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash, 0n); + expect(maybeIndexAndPath).toBeDefined(); + const messageLeafIndex = maybeIndexAndPath![0]; + // 3. Consume L1 -> L2 message and mint public tokens on L2 - await crossChainTestHarness.consumeMessageOnAztecAndMintPublicly(bridgeAmount, secret); + await crossChainTestHarness.consumeMessageOnAztecAndMintPublicly(bridgeAmount, secret, messageLeafIndex); await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount); const afterBalance = bridgeAmount; @@ -161,14 +168,26 @@ describe('e2e_public_cross_chain_messaging', () => { secretHash, ); + // get message leaf index, needed for claiming in public + const maybeIndexAndPath = await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash, 0n); + expect(maybeIndexAndPath).toBeDefined(); + const messageLeafIndex = maybeIndexAndPath![0]; + // user2 tries to consume this message and minting to itself -> should fail since the message is intended to be consumed only by owner. await expect( - l2Bridge.withWallet(user2Wallet).methods.claim_public(user2Wallet.getAddress(), bridgeAmount, secret).prove(), + l2Bridge + .withWallet(user2Wallet) + .methods.claim_public(user2Wallet.getAddress(), bridgeAmount, secret, messageLeafIndex) + .prove(), ).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`); // user2 consumes owner's L1-> L2 message on bridge contract and mints public tokens on L2 logger.info("user2 consumes owner's message on L2 Publicly"); - await l2Bridge.withWallet(user2Wallet).methods.claim_public(ownerAddress, bridgeAmount, secret).send().wait(); + await l2Bridge + .withWallet(user2Wallet) + .methods.claim_public(ownerAddress, bridgeAmount, secret, messageLeafIndex) + .send() + .wait(); // ensure funds are gone to owner and not user2. await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount); await crossChainTestHarness.expectPublicBalanceOnL2(user2Wallet.getAddress(), 0n); @@ -312,7 +331,8 @@ describe('e2e_public_cross_chain_messaging', () => { const testContract = await TestContract.deploy(user1Wallet).send().deployed(); const consumeMethod = isPrivate - ? testContract.methods.consume_message_from_arbitrary_sender_private + ? (content: FieldLike, secret: FieldLike, sender: EthAddressLike, _leafIndex: FieldLike) => + testContract.methods.consume_message_from_arbitrary_sender_private(content, secret, sender) : testContract.methods.consume_message_from_arbitrary_sender_public; const secret = Fr.random(); @@ -329,7 +349,7 @@ describe('e2e_public_cross_chain_messaging', () => { const [message1Index, _1] = (await aztecNode.getL1ToL2MessageMembershipWitness('latest', message.hash(), 0n))!; // Finally, we consume the L1 -> L2 message using the test contract either from private or public - await consumeMethod(message.content, secret, message.sender.sender).send().wait(); + await consumeMethod(message.content, secret, message.sender.sender, message1Index).send().wait(); // We send and consume the exact same message the second time to test that oracles correctly return the new // non-nullified message @@ -348,7 +368,7 @@ describe('e2e_public_cross_chain_messaging', () => { // Now we consume the message again. Everything should pass because oracle should return the duplicate message // which is not nullified - await consumeMethod(message.content, secret, message.sender.sender).send().wait(); + await consumeMethod(message.content, secret, message.sender.sender, message2Index).send().wait(); }, 120_000, ); diff --git a/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts b/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts index 805628e74a85..51077dc9de89 100644 --- a/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts @@ -1,4 +1,4 @@ -import { type AztecAddress, type DebugLogger, type EthAddress } from '@aztec/aztec.js'; +import { type AztecAddress, type AztecNode, type DebugLogger, type EthAddress } from '@aztec/aztec.js'; import { setup } from './fixtures/utils.js'; import { CrossChainTestHarness } from './shared/cross_chain_test_harness.js'; @@ -7,18 +7,23 @@ describe('e2e_public_to_private_messaging', () => { let logger: DebugLogger; let teardown: () => Promise; + let aztecNode: AztecNode; let ethAccount: EthAddress; - let underlyingERC20: any; - let ownerAddress: AztecAddress; - let crossChainTestHarness: CrossChainTestHarness; beforeEach(async () => { - const { aztecNode, pxe, deployL1ContractsValues, wallet, logger: logger_, teardown: teardown_ } = await setup(2); + const { + aztecNode: aztecNode_, + pxe, + deployL1ContractsValues, + wallet, + logger: logger_, + teardown: teardown_, + } = await setup(2); crossChainTestHarness = await CrossChainTestHarness.new( - aztecNode, + aztecNode_, pxe, deployL1ContractsValues.publicClient, deployL1ContractsValues.walletClient, @@ -26,6 +31,7 @@ describe('e2e_public_to_private_messaging', () => { logger_, ); + aztecNode = crossChainTestHarness.aztecNode; ethAccount = crossChainTestHarness.ethAccount; ownerAddress = crossChainTestHarness.ownerAddress; underlyingERC20 = crossChainTestHarness.underlyingERC20; @@ -53,7 +59,12 @@ describe('e2e_public_to_private_messaging', () => { await crossChainTestHarness.makeMessageConsumable(msgHash); - await crossChainTestHarness.consumeMessageOnAztecAndMintPublicly(bridgeAmount, secret); + // get message leaf index, needed for claiming in public + const maybeIndexAndPath = await aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash, 0n); + expect(maybeIndexAndPath).toBeDefined(); + const messageLeafIndex = maybeIndexAndPath![0]; + + await crossChainTestHarness.consumeMessageOnAztecAndMintPublicly(bridgeAmount, secret, messageLeafIndex); await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount); // Create the commitment to be spent in the private domain diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index 56783ceee2ee..8a6ed6dc23ea 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -1,5 +1,5 @@ -import { type Wallet } from '@aztec/aztec.js'; -import { DocsExampleContract } from '@aztec/noir-contracts.js'; +import { AztecAddress, Fr, type PXE, type Wallet } from '@aztec/aztec.js'; +import { AuthContract, DocsExampleContract, TestContract } from '@aztec/noir-contracts.js'; import { jest } from '@jest/globals'; @@ -8,6 +8,7 @@ import { setup } from './fixtures/utils.js'; const TIMEOUT = 100_000; describe('e2e_state_vars', () => { + let pxe: PXE; jest.setTimeout(TIMEOUT); let wallet: Wallet; @@ -19,7 +20,7 @@ describe('e2e_state_vars', () => { const RANDOMNESS = 2n; beforeAll(async () => { - ({ teardown, wallet } = await setup()); + ({ teardown, wallet, pxe } = await setup(2)); contract = await DocsExampleContract.deploy(wallet).send().deployed(); }, 30_000); @@ -38,6 +39,7 @@ describe('e2e_state_vars', () => { // checking the return values with: // 1. A constrained private function that reads it directly // 2. A constrained private function that calls another private function that reads. + // The indirect, adds 1 to the point to ensure that we are returning the correct value. await contract.methods.initialize_shared_immutable(1).send().wait(); @@ -45,12 +47,8 @@ describe('e2e_state_vars', () => { const b = await contract.methods.get_shared_immutable_constrained_private_indirect().simulate(); const c = await contract.methods.get_shared_immutable().simulate(); - expect((a as any)[0]).toEqual((c as any)['account'].toBigInt()); - expect((a as any)[1]).toEqual((c as any)['points']); - expect((b as any)[0]).toEqual((c as any)['account'].toBigInt()); - expect((b as any)[1]).toEqual((c as any)['points']); - - expect(a).toEqual(b); + expect(a).toEqual(c); + expect(b).toEqual({ account: c.account, points: c.points + 1n }); await contract.methods.match_shared_immutable(c.account, c.points).send().wait(); }); @@ -58,20 +56,28 @@ describe('e2e_state_vars', () => { // Reads the value using an unconstrained function checking the return values with: // 1. A constrained public function that reads it directly // 2. A constrained public function that calls another public function that reads. + // The indirect, adds 1 to the point to ensure that we are returning the correct value. const a = await contract.methods.get_shared_immutable_constrained_public().simulate(); const b = await contract.methods.get_shared_immutable_constrained_public_indirect().simulate(); const c = await contract.methods.get_shared_immutable().simulate(); - expect((a as any)[0]).toEqual((c as any)['account'].toBigInt()); - expect((a as any)[1]).toEqual((c as any)['points']); - expect((b as any)[0]).toEqual((c as any)['account'].toBigInt()); - expect((b as any)[1]).toEqual((c as any)['points']); + expect(a).toEqual(c); + expect(b).toEqual({ account: c.account, points: c.points + 1n }); - expect(a).toEqual(b); await contract.methods.match_shared_immutable(c.account, c.points).send().wait(); }); + it('public multiread of SharedImmutable', async () => { + // Reads the value using an unconstrained function checking the return values with: + // 1. A constrained public function that reads 5 times directly (going beyond the previous 4 Field return value) + + const a = await contract.methods.get_shared_immutable_constrained_public_multiple().simulate(); + const c = await contract.methods.get_shared_immutable().simulate(); + + expect(a).toEqual([c, c, c, c, c]); + }); + it('initializing SharedImmutable the second time should fail', async () => { // Jest executes the tests sequentially and the first call to initialize_shared_immutable was executed // in the previous test, so the call bellow should fail. @@ -217,4 +223,53 @@ describe('e2e_state_vars', () => { expect(randomness).toEqual(RANDOMNESS); }); }); + + describe('SharedMutablePrivateGetter', () => { + let authContract: AuthContract; + let testContract: TestContract; + + const delay = async (blocks: number) => { + for (let i = 0; i < blocks; i++) { + await authContract.methods.get_authorized().send().wait(); + } + }; + + beforeAll(async () => { + testContract = await TestContract.deploy(wallet).send().deployed(); + // We use the auth contract here because has a nice, clear, simple implementation of the Shared Mutable, + // and we will need to read from it to test our private getter. + authContract = await AuthContract.deploy(wallet, wallet.getAddress()).send().deployed(); + + // We set the authorized value here, knowing there will be some delay before the value change takes place + await authContract + .withWallet(wallet) + .methods.set_authorized(AztecAddress.fromField(new Fr(6969696969))) + .send() + .wait(); + }, 30_000); + + it("checks authorized in auth contract from test contract and finds the old value because the change hasn't been applied yet", async () => { + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter(authContract.address, 2) + .send() + .wait(); + + // The function above emits an unencrypted log as a means of returning the data + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(0)); + }); + + it('checks authorized in auth contract from test contract and finds the correctly set value', async () => { + await delay(5); + + const { txHash } = await testContract.methods + .test_shared_mutable_private_getter(authContract.address, 2) + .send() + .wait(); + + // The function above emits an unencrypted log as a means of returning the data + const rawLogs = await pxe.getUnencryptedLogs({ txHash }); + expect(Fr.fromBuffer(rawLogs.logs[0].log.data)).toEqual(new Fr(6969696969)); + }); + }); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts index dfdacb8ab2a9..b7a5089217f6 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts @@ -87,7 +87,7 @@ describe('e2e_token_contract reading constants', () => { await reader.methods.check_symbol_public(t.asset.address, TOKEN_SYMBOL).send().wait(); await expect(reader.methods.check_symbol_public(t.asset.address, 'WRONG_SYMBOL').simulate()).rejects.toThrow( - "Failed to solve brillig function, reason: explicit trap hit in brillig 'symbol.is_eq(_what)'", + "Failed to solve brillig function 'symbol.is_eq(_what)'", ); }); @@ -109,7 +109,7 @@ describe('e2e_token_contract reading constants', () => { await reader.methods.check_decimals_public(t.asset.address, TOKEN_DECIMALS).send().wait(); await expect(reader.methods.check_decimals_public(t.asset.address, 99).simulate()).rejects.toThrow( - "Failed to solve brillig function, reason: explicit trap hit in brillig 'ret == what'", + "Failed to solve brillig function 'ret == what'", ); }); }); diff --git a/yarn-project/end-to-end/src/e2e_account_init_fees.test.ts b/yarn-project/end-to-end/src/flakey_e2e_account_init_fees.test.ts similarity index 95% rename from yarn-project/end-to-end/src/e2e_account_init_fees.test.ts rename to yarn-project/end-to-end/src/flakey_e2e_account_init_fees.test.ts index 94f7321a0ae9..9f0d16ed8102 100644 --- a/yarn-project/end-to-end/src/e2e_account_init_fees.test.ts +++ b/yarn-project/end-to-end/src/flakey_e2e_account_init_fees.test.ts @@ -15,7 +15,7 @@ import { computeMessageSecretHash, generatePublicKey, } from '@aztec/aztec.js'; -import { type AztecAddress, CompleteAddress, Fq } from '@aztec/circuits.js'; +import { type AztecAddress, CompleteAddress, DimensionGasSettings, Fq, GasSettings } from '@aztec/circuits.js'; import { TokenContract as BananaCoin, FPCContract, @@ -70,6 +70,7 @@ describe('e2e_fees_account_init', () => { let fpcsInitialGas: bigint; let fpcsInitialPublicBananas: bigint; + let gasSettings: GasSettings; let maxFee: bigint; let actualFee: bigint; @@ -93,6 +94,7 @@ describe('e2e_fees_account_init', () => { }); gasBridgeTestHarness = await GasPortalTestingHarnessFactory.create({ + aztecNode: ctx.aztecNode, pxeService: ctx.pxe, publicClient: ctx.deployL1ContractsValues.publicClient, walletClient: ctx.deployL1ContractsValues.walletClient, @@ -123,7 +125,9 @@ describe('e2e_fees_account_init', () => { afterAll(() => ctx.teardown()); beforeEach(() => { - maxFee = 3n; + const individualGasSettings = new DimensionGasSettings(2, 1, Fr.ONE); + gasSettings = new GasSettings(individualGasSettings, individualGasSettings, individualGasSettings, new Fr(5)); + maxFee = 3n * 3n + 5n; actualFee = 1n; bobsPrivateEncryptionKey = Fq.random(); bobsPrivateSigningKey = Fq.random(); @@ -143,7 +147,7 @@ describe('e2e_fees_account_init', () => { await bobsAccountManager .deploy({ fee: { - maxFee, + gasSettings, paymentMethod: await NativeFeePaymentMethod.create(await bobsAccountManager.getWallet()), }, }) @@ -188,7 +192,7 @@ describe('e2e_fees_account_init', () => { const tx = await bobsAccountManager .deploy({ fee: { - maxFee, + gasSettings, paymentMethod: new PrivateFeePaymentMethod( bananaCoin.address, bananaFPC.address, @@ -246,7 +250,7 @@ describe('e2e_fees_account_init', () => { .deploy({ skipPublicDeployment: false, fee: { - maxFee, + gasSettings, paymentMethod: new PublicFeePaymentMethod( bananaCoin.address, bananaFPC.address, @@ -301,7 +305,7 @@ describe('e2e_fees_account_init', () => { skipInitialization: false, universalDeploy: true, fee: { - maxFee, + gasSettings, paymentMethod: await NativeFeePaymentMethod.create(alice), }, }) diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts b/yarn-project/end-to-end/src/flakey_e2e_deploy_contract/contract_class_registration.test.ts similarity index 100% rename from yarn-project/end-to-end/src/e2e_deploy_contract/contract_class_registration.test.ts rename to yarn-project/end-to-end/src/flakey_e2e_deploy_contract/contract_class_registration.test.ts diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts b/yarn-project/end-to-end/src/flakey_e2e_deploy_contract/deploy_method.test.ts similarity index 100% rename from yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts rename to yarn-project/end-to-end/src/flakey_e2e_deploy_contract/deploy_method.test.ts diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts b/yarn-project/end-to-end/src/flakey_e2e_deploy_contract/deploy_test.ts similarity index 100% rename from yarn-project/end-to-end/src/e2e_deploy_contract/deploy_test.ts rename to yarn-project/end-to-end/src/flakey_e2e_deploy_contract/deploy_test.ts diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts b/yarn-project/end-to-end/src/flakey_e2e_deploy_contract/legacy.test.ts similarity index 100% rename from yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts rename to yarn-project/end-to-end/src/flakey_e2e_deploy_contract/legacy.test.ts diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts b/yarn-project/end-to-end/src/flakey_e2e_deploy_contract/private_initialization.test.ts similarity index 100% rename from yarn-project/end-to-end/src/e2e_deploy_contract/private_initialization.test.ts rename to yarn-project/end-to-end/src/flakey_e2e_deploy_contract/private_initialization.test.ts diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/regressions.test.ts b/yarn-project/end-to-end/src/flakey_e2e_deploy_contract/regressions.test.ts similarity index 100% rename from yarn-project/end-to-end/src/e2e_deploy_contract/regressions.test.ts rename to yarn-project/end-to-end/src/flakey_e2e_deploy_contract/regressions.test.ts diff --git a/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts b/yarn-project/end-to-end/src/flakey_e2e_inclusion_proofs_contract.test.ts similarity index 100% rename from yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts rename to yarn-project/end-to-end/src/flakey_e2e_inclusion_proofs_contract.test.ts diff --git a/yarn-project/end-to-end/src/e2e_p2p_network.test.ts b/yarn-project/end-to-end/src/flakey_e2e_p2p_network.test.ts similarity index 100% rename from yarn-project/end-to-end/src/e2e_p2p_network.test.ts rename to yarn-project/end-to-end/src/flakey_e2e_p2p_network.test.ts diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 342e0ce917f2..63975935c910 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -319,10 +319,10 @@ export class CrossChainTestHarness { await this.addPendingShieldNoteToPXE(bridgeAmount, secretHashForRedeemingMintedNotes, consumptionReceipt.txHash); } - async consumeMessageOnAztecAndMintPublicly(bridgeAmount: bigint, secret: Fr) { + async consumeMessageOnAztecAndMintPublicly(bridgeAmount: bigint, secret: Fr, leafIndex: bigint) { this.logger.info('Consuming messages on L2 Publicly'); // Call the mint tokens function on the Aztec.nr contract - await this.l2Bridge.methods.claim_public(this.ownerAddress, bridgeAmount, secret).send().wait(); + await this.l2Bridge.methods.claim_public(this.ownerAddress, bridgeAmount, secret, leafIndex).send().wait(); } async withdrawPrivateFromAztecToL1(withdrawAmount: bigint, nonce: Fr = Fr.ZERO): Promise> { diff --git a/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts b/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts index 1897042ab050..7a0c7625302c 100644 --- a/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/gas_portal_test_harness.ts @@ -1,5 +1,6 @@ import { type AztecAddress, + type AztecNode, type DebugLogger, EthAddress, Fr, @@ -27,6 +28,7 @@ export interface IGasBridgingTestHarness { } export interface GasPortalTestingHarnessFactoryConfig { + aztecNode: AztecNode; pxeService: PXE; publicClient: PublicClient; walletClient: WalletClient; @@ -34,6 +36,7 @@ export interface GasPortalTestingHarnessFactoryConfig { logger: DebugLogger; mockL1?: boolean; } + export class GasPortalTestingHarnessFactory { private constructor(private config: GasPortalTestingHarnessFactoryConfig) {} @@ -49,7 +52,7 @@ export class GasPortalTestingHarnessFactory { } private async createReal() { - const { pxeService, publicClient, walletClient, wallet, logger } = this.config; + const { aztecNode, pxeService, publicClient, walletClient, wallet, logger } = this.config; const ethAccount = EthAddress.fromString((await walletClient.getAddresses())[0]); const l1ContractAddresses = (await pxeService.getNodeInfo()).l1ContractAddresses; @@ -82,6 +85,7 @@ export class GasPortalTestingHarnessFactory { const gasL2 = await GasTokenContract.at(getCanonicalGasTokenAddress(gasPortalAddress), wallet); return new GasBridgingTestHarness( + aztecNode, pxeService, logger, gasL2, @@ -118,6 +122,8 @@ class MockGasBridgingTestHarness implements IGasBridgingTestHarness { */ class GasBridgingTestHarness implements IGasBridgingTestHarness { constructor( + /** Aztec node */ + public aztecNode: AztecNode, /** Private eXecution Environment (PXE). */ public pxeService: PXE, /** Logger. */ @@ -201,10 +207,10 @@ class GasBridgingTestHarness implements IGasBridgingTestHarness { return Fr.fromString(messageHash); } - async consumeMessageOnAztecAndMintPublicly(bridgeAmount: bigint, owner: AztecAddress, secret: Fr) { + async consumeMessageOnAztecAndMintPublicly(bridgeAmount: bigint, owner: AztecAddress, secret: Fr, leafIndex: bigint) { this.logger.info('Consuming messages on L2 Publicly'); // Call the mint tokens function on the Aztec.nr contract - await this.l2Token.methods.claim_public(owner, bridgeAmount, secret).send().wait(); + await this.l2Token.methods.claim_public(owner, bridgeAmount, secret, leafIndex).send().wait(); } async getL2PublicBalanceOf(owner: AztecAddress) { @@ -223,15 +229,20 @@ class GasBridgingTestHarness implements IGasBridgingTestHarness { await this.mintTokensOnL1(l1TokenBalance); // 2. Deposit tokens to the TokenPortal - await this.sendTokensToPortalPublic(bridgeAmount, owner, secretHash); + const msgHash = await this.sendTokensToPortalPublic(bridgeAmount, owner, secretHash); expect(await this.getL1BalanceOf(this.ethAccount)).toBe(l1TokenBalance - bridgeAmount); // Perform an unrelated transactions on L2 to progress the rollup by 2 blocks. await this.l2Token.methods.check_balance(0).send().wait(); await this.l2Token.methods.check_balance(0).send().wait(); + // Get message leaf index, needed for claiming in public + const maybeIndexAndPath = await this.aztecNode.getL1ToL2MessageMembershipWitness('latest', msgHash, 0n); + expect(maybeIndexAndPath).toBeDefined(); + const messageLeafIndex = maybeIndexAndPath![0]; + // 3. Consume L1-> L2 message and mint public tokens on L2 - await this.consumeMessageOnAztecAndMintPublicly(bridgeAmount, owner, secret); + await this.consumeMessageOnAztecAndMintPublicly(bridgeAmount, owner, secret, messageLeafIndex); await this.expectPublicBalanceOnL2(owner, bridgeAmount); } } diff --git a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index 81dc6b3cb4c1..f23c35ea442a 100644 --- a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -14,6 +14,7 @@ import { InboxAbi, UniswapPortalAbi, UniswapPortalBytecode } from '@aztec/l1-art import { UniswapContract } from '@aztec/noir-contracts.js/Uniswap'; import { jest } from '@jest/globals'; +import { strict as assert } from 'assert'; import { type Account, type Chain, @@ -409,9 +410,22 @@ export const uniswapL1L2TestSuite = ( // Wait for the message to be available for consumption await wethCrossChainHarness.makeMessageConsumable(wethDepositMsgHash); + // Get message leaf index, needed for claiming in public + const wethDepositMaybeIndexAndPath = await aztecNode.getL1ToL2MessageMembershipWitness( + 'latest', + wethDepositMsgHash, + 0n, + ); + assert(wethDepositMaybeIndexAndPath !== undefined, 'Message not found in tree'); + const wethDepositMessageLeafIndex = wethDepositMaybeIndexAndPath[0]; + // 2. Claim WETH on L2 logger.info('Minting weth on L2'); - await wethCrossChainHarness.consumeMessageOnAztecAndMintPublicly(wethAmountToBridge, secretForMintingWeth); + await wethCrossChainHarness.consumeMessageOnAztecAndMintPublicly( + wethAmountToBridge, + secretForMintingWeth, + wethDepositMessageLeafIndex, + ); await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, wethAmountToBridge); // Store balances @@ -585,9 +599,22 @@ export const uniswapL1L2TestSuite = ( // Wait for the message to be available for consumption await daiCrossChainHarness.makeMessageConsumable(outTokenDepositMsgHash); + // Get message leaf index, needed for claiming in public + const outTokenDepositMaybeIndexAndPath = await aztecNode.getL1ToL2MessageMembershipWitness( + 'latest', + outTokenDepositMsgHash, + 0n, + ); + assert(outTokenDepositMaybeIndexAndPath !== undefined, 'Message not found in tree'); + const outTokenDepositMessageLeafIndex = outTokenDepositMaybeIndexAndPath[0]; + // 6. claim dai on L2 logger.info('Consuming messages to mint dai on L2'); - await daiCrossChainHarness.consumeMessageOnAztecAndMintPublicly(daiAmountToBridge, secretForDepositingSwappedDai); + await daiCrossChainHarness.consumeMessageOnAztecAndMintPublicly( + daiAmountToBridge, + secretForDepositingSwappedDai, + outTokenDepositMessageLeafIndex, + ); await daiCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, daiL2BalanceBeforeSwap + daiAmountToBridge); const wethL2BalanceAfterSwap = await wethCrossChainHarness.getL2PublicBalanceOf(ownerAddress); diff --git a/yarn-project/entrypoints/src/account_entrypoint.ts b/yarn-project/entrypoints/src/account_entrypoint.ts index 84a78f8b1a96..fccd48001777 100644 --- a/yarn-project/entrypoints/src/account_entrypoint.ts +++ b/yarn-project/entrypoints/src/account_entrypoint.ts @@ -1,7 +1,7 @@ import { type AuthWitnessProvider } from '@aztec/aztec.js/account'; import { type EntrypointInterface, EntrypointPayload, type ExecutionRequestInit } from '@aztec/aztec.js/entrypoint'; import { PackedValues, TxExecutionRequest } from '@aztec/circuit-types'; -import { type AztecAddress, FunctionData, TxContext } from '@aztec/circuits.js'; +import { type AztecAddress, FunctionData, GasSettings, TxContext } from '@aztec/circuits.js'; import { type FunctionAbi, encodeArguments } from '@aztec/foundation/abi'; import { DEFAULT_CHAIN_ID, DEFAULT_VERSION } from './constants.js'; @@ -36,6 +36,7 @@ export class DefaultAccountEntrypoint implements EntrypointInterface { txContext: TxContext.empty(this.chainId, this.version), packedArguments: [...appPayload.packedArguments, ...feePayload.packedArguments, entrypointPackedArgs], authWitnesses: [appAuthWitness, feeAuthWitness], + gasSettings: exec.fee?.gasSettings ?? GasSettings.default(), }); return txRequest; diff --git a/yarn-project/entrypoints/src/dapp_entrypoint.ts b/yarn-project/entrypoints/src/dapp_entrypoint.ts index a65e501d1aba..55381e04cc01 100644 --- a/yarn-project/entrypoints/src/dapp_entrypoint.ts +++ b/yarn-project/entrypoints/src/dapp_entrypoint.ts @@ -2,7 +2,7 @@ import { computeInnerAuthWitHash, computeOuterAuthWitHash } from '@aztec/aztec.j import { type AuthWitnessProvider } from '@aztec/aztec.js/account'; import { type EntrypointInterface, EntrypointPayload, type ExecutionRequestInit } from '@aztec/aztec.js/entrypoint'; import { PackedValues, TxExecutionRequest } from '@aztec/circuit-types'; -import { type AztecAddress, Fr, FunctionData, TxContext } from '@aztec/circuits.js'; +import { type AztecAddress, Fr, FunctionData, GasSettings, TxContext } from '@aztec/circuits.js'; import { type FunctionAbi, encodeArguments } from '@aztec/foundation/abi'; import { DEFAULT_CHAIN_ID, DEFAULT_VERSION } from './constants.js'; @@ -50,6 +50,7 @@ export class DefaultDappEntrypoint implements EntrypointInterface { txContext: TxContext.empty(this.chainId, this.version), packedArguments: [...payload.packedArguments, entrypointPackedArgs], authWitnesses: [authWitness], + gasSettings: exec.fee?.gasSettings ?? GasSettings.default(), }); return txRequest; diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts index 1a9fb2b89014..9f2d48800f8e 100644 --- a/yarn-project/foundation/src/abi/abi.ts +++ b/yarn-project/foundation/src/abi/abi.ts @@ -240,6 +240,16 @@ export interface DebugInfo { locations: Record; } +/** + * The debug information for a given program (a collection of functions) + */ +export interface ProgramDebugInfo { + /** + * A list of debug information that matches with each function in a program + */ + debug_infos: Array; +} + /** * Maps a file ID to its metadata for debugging purposes. */ @@ -355,10 +365,13 @@ export function getFunctionDebugMetadata( functionArtifact: FunctionArtifact, ): FunctionDebugMetadata | undefined { if (functionArtifact.debugSymbols && contractArtifact.fileMap) { - const debugSymbols = JSON.parse( + const programDebugSymbols = JSON.parse( inflate(Buffer.from(functionArtifact.debugSymbols, 'base64'), { to: 'string', raw: true }), ); - return { debugSymbols, files: contractArtifact.fileMap }; + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/5813) + // We only support handling debug info for the contract function entry point. + // So for now we simply index into the first debug info. + return { debugSymbols: programDebugSymbols.debug_infos[0], files: contractArtifact.fileMap }; } return undefined; } diff --git a/yarn-project/foundation/src/abi/decoder.ts b/yarn-project/foundation/src/abi/decoder.ts index deafe602ae1c..c98bac638239 100644 --- a/yarn-project/foundation/src/abi/decoder.ts +++ b/yarn-project/foundation/src/abi/decoder.ts @@ -1,20 +1,19 @@ import { AztecAddress } from '../aztec-address/index.js'; import { type Fr } from '../fields/index.js'; -import { type ABIParameter, type ABIVariable, type AbiType, type FunctionArtifact } from './abi.js'; +import { type ABIParameter, type ABIVariable, type AbiType, type FunctionAbi } from './abi.js'; import { isAztecAddressStruct } from './utils.js'; /** * The type of our decoded ABI. */ export type DecodedReturn = bigint | boolean | AztecAddress | DecodedReturn[] | { [key: string]: DecodedReturn }; -export type ProcessReturnValues = (DecodedReturn | undefined)[] | undefined; /** * Decodes return values from a function call. * Missing support for integer and string. */ class ReturnValuesDecoder { - constructor(private artifact: FunctionArtifact, private flattened: Fr[]) {} + constructor(private artifact: FunctionAbi, private flattened: Fr[]) {} /** * Decodes a single return value from field to the given type. @@ -97,7 +96,7 @@ class ReturnValuesDecoder { * @param returnValues - The decoded return values. * @returns */ -export function decodeReturnValues(abi: FunctionArtifact, returnValues: Fr[]) { +export function decodeReturnValues(abi: FunctionAbi, returnValues: Fr[]) { return new ReturnValuesDecoder(abi, returnValues.slice()).decode(); } diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts index 2002be8f5963..d09669d7ce30 100644 --- a/yarn-project/foundation/src/abi/function_selector.ts +++ b/yarn-project/foundation/src/abi/function_selector.ts @@ -21,10 +21,10 @@ export class FunctionSelector extends Selector { * Checks if this function selector is equal to another. * @returns True if the function selectors are equal. */ - equals(fn: { name: string; parameters: ABIParameter[] }): boolean; - equals(otherName: string, otherParams: ABIParameter[]): boolean; - equals(other: FunctionSelector): boolean; - equals( + override equals(fn: { name: string; parameters: ABIParameter[] }): boolean; + override equals(otherName: string, otherParams: ABIParameter[]): boolean; + override equals(other: FunctionSelector): boolean; + override equals( other: FunctionSelector | string | { name: string; parameters: ABIParameter[] }, otherParams?: ABIParameter[], ): boolean { diff --git a/yarn-project/foundation/src/aztec-address/index.ts b/yarn-project/foundation/src/aztec-address/index.ts index e97fb1f17946..53229d1fda7a 100644 --- a/yarn-project/foundation/src/aztec-address/index.ts +++ b/yarn-project/foundation/src/aztec-address/index.ts @@ -23,13 +23,13 @@ export class AztecAddress extends Fr { return `AztecAddress<${this.toString()}>`; } - static ZERO = new AztecAddress(Buffer.alloc(32)); + static override ZERO = new AztecAddress(Buffer.alloc(32)); - static zero(): AztecAddress { + static override zero(): AztecAddress { return AztecAddress.ZERO; } - static fromBuffer(buffer: Buffer | BufferReader) { + static override fromBuffer(buffer: Buffer | BufferReader) { return fromBuffer(buffer, AztecAddress); } @@ -46,16 +46,16 @@ export class AztecAddress extends Fr { return AztecAddress.fromField(new Fr(value)); } - static fromString(buf: string) { + static override fromString(buf: string) { const buffer = Buffer.from(buf.replace(/^0x/i, ''), 'hex'); return new AztecAddress(buffer); } - static random() { + static override random() { return new AztecAddress(super.random().toBuffer()); } - toJSON() { + override toJSON() { return { type: 'AztecAddress', value: this.toString(), diff --git a/yarn-project/foundation/src/fields/fields.ts b/yarn-project/foundation/src/fields/fields.ts index bc180fa9ecb6..8aaa93458748 100644 --- a/yarn-project/foundation/src/fields/fields.ts +++ b/yarn-project/foundation/src/fields/fields.ts @@ -188,6 +188,7 @@ export interface Fr { */ export class Fr extends BaseField { static ZERO = new Fr(0n); + static ONE = new Fr(1n); static MODULUS = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n; constructor(value: number | bigint | boolean | Fr | Buffer) { @@ -372,7 +373,7 @@ function extendedEuclidean(a: bigint, modulus: bigint): [bigint, bigint, bigint] /** * GrumpkinScalar is an Fq. * @remarks Called GrumpkinScalar because it is used to represent elements in Grumpkin's scalar field as defined in - * the Aztec Yellow Paper. + * the Aztec Protocol Specs. */ export type GrumpkinScalar = Fq; export const GrumpkinScalar = Fq; diff --git a/yarn-project/key-store/src/new_test_key_store.test.ts b/yarn-project/key-store/src/new_test_key_store.test.ts index 7e56a873ac8d..c67347242a83 100644 --- a/yarn-project/key-store/src/new_test_key_store.test.ts +++ b/yarn-project/key-store/src/new_test_key_store.test.ts @@ -55,5 +55,17 @@ describe('NewTestKeyStore', () => { expect(appOutgoingViewingSecretKey.toString()).toMatchInlineSnapshot( `"0x2639b26510f9d30b7e173d301b263b246b7a576186be1f44cd7c86bc06773f8a"`, ); + + // Returned accounts are as expected + const accounts = await keyStore.getAccounts(); + expect(accounts.toString()).toMatchInlineSnapshot( + `"0x0ba7834252d19c4f09d29303c269f303f40ae3d2043f921ed0bf8c0709926d4e"`, + ); + + // Manages to find master nullifer secret key for pub key + const masterNullifierSecretKey = await keyStore.getMasterNullifierSecretKeyForPublicKey(masterNullifierPublicKey); + expect(masterNullifierSecretKey.toString()).toMatchInlineSnapshot( + `"0x0fde74d5e504c73b58aad420dd72590fc6004571411e7f77c45378714195a52b"`, + ); }); }); diff --git a/yarn-project/key-store/src/new_test_key_store.ts b/yarn-project/key-store/src/new_test_key_store.ts index c5ff22030e70..23d2028c4954 100644 --- a/yarn-project/key-store/src/new_test_key_store.ts +++ b/yarn-project/key-store/src/new_test_key_store.ts @@ -1,5 +1,13 @@ import { type NewKeyStore, type PublicKey } from '@aztec/circuit-types'; -import { AztecAddress, Fr, GeneratorIndex, GrumpkinScalar, type PartialAddress, Point } from '@aztec/circuits.js'; +import { + AztecAddress, + Fr, + GeneratorIndex, + type GrumpkinPrivateKey, + GrumpkinScalar, + type PartialAddress, + Point, +} from '@aztec/circuits.js'; import { type Grumpkin } from '@aztec/circuits.js/barretenberg'; import { poseidon2Hash, sha512ToGrumpkinScalar } from '@aztec/foundation/crypto'; import { type AztecKVStore, type AztecMap } from '@aztec/kv-store'; @@ -75,6 +83,17 @@ export class NewTestKeyStore implements NewKeyStore { return Promise.resolve(accountAddress); } + /** + * Retrieves addresses of accounts stored in the key store. + * @returns A Promise that resolves to an array of account addresses. + */ + public getAccounts(): Promise { + const allMapKeys = Array.from(this.#keys.keys()); + // We return account addresses based on the map keys that end with '-nsk_m' + const accounts = allMapKeys.filter(key => key.endsWith('-nsk_m')).map(key => key.split('-')[0]); + return Promise.resolve(accounts.map(account => AztecAddress.fromString(account))); + } + /** * Gets the master nullifier public key for a given account. * @throws If the account does not exist in the key store. @@ -197,4 +216,30 @@ export class NewTestKeyStore implements NewKeyStore { ]), ); } + + /** + * Retrieves the master nullifier secret key (nsk_m) corresponding to the specified master nullifier public key + * (Npk_m). + * @throws If the provided public key is not associated with any of the registered accounts. + * @param masterNullifierPublicKey - The master nullifier public key to get secret key for. + * @returns A Promise that resolves to the master nullifier secret key. + * @dev Used when feeding the master nullifier secret key to the kernel circuit for nullifier keys verification. + */ + public getMasterNullifierSecretKeyForPublicKey(masterNullifierPublicKey: PublicKey): Promise { + // We iterate over the map keys to find the account address that corresponds to the provided public key + for (const [key, value] of this.#keys.entries()) { + if (value.equals(masterNullifierPublicKey.toBuffer())) { + // We extract the account address from the map key + const accountAddress = key.split('-')[0]; + // We fetch the secret key and return it + const masterNullifierSecretKeyBuffer = this.#keys.get(`${accountAddress.toString()}-nsk_m`); + if (!masterNullifierSecretKeyBuffer) { + throw new Error(`Could not find master nullifier secret key for account ${accountAddress.toString()}`); + } + return Promise.resolve(GrumpkinScalar.fromBuffer(masterNullifierSecretKeyBuffer)); + } + } + + throw new Error(`Could not find master nullifier secret key for public key ${masterNullifierPublicKey.toString()}`); + } } diff --git a/yarn-project/kv-store/package.json b/yarn-project/kv-store/package.json index d5bfb66aec49..d22d0190c7da 100644 --- a/yarn-project/kv-store/package.json +++ b/yarn-project/kv-store/package.json @@ -37,7 +37,7 @@ }, "dependencies": { "@aztec/foundation": "workspace:^", - "lmdb": "^2.9.2" + "lmdb": "^3.0.6" }, "devDependencies": { "@jest/globals": "^29.5.0", diff --git a/yarn-project/merkle-tree/src/snapshots/indexed_tree_snapshot.ts b/yarn-project/merkle-tree/src/snapshots/indexed_tree_snapshot.ts index c39108239d9e..1d70549450da 100644 --- a/yarn-project/merkle-tree/src/snapshots/indexed_tree_snapshot.ts +++ b/yarn-project/merkle-tree/src/snapshots/indexed_tree_snapshot.ts @@ -23,7 +23,7 @@ export class IndexedTreeSnapshotBuilder return new IndexedTreeSnapshotImpl(this.nodes, this.leaves, root, numLeaves, this.tree, this.leafPreimageBuilder); } - protected handleLeaf(index: bigint, node: Buffer) { + protected override handleLeaf(index: bigint, node: Buffer) { const leafPreimage = this.tree.getLatestLeafPreimageCopy(index, false); if (leafPreimage) { void this.leaves.set(snapshotLeafValue(node, index), leafPreimage.toBuffer()); @@ -44,7 +44,7 @@ class IndexedTreeSnapshotImpl extends BaseFullTreeSnapshot implements In super(db, historicRoot, numLeaves, tree, { fromBuffer: buf => buf }); } - getLeafValue(index: bigint): Buffer | undefined { + override getLeafValue(index: bigint): Buffer | undefined { const leafPreimage = this.getLatestLeafPreimageCopy(index); return leafPreimage?.toBuffer(); } @@ -99,7 +99,7 @@ class IndexedTreeSnapshotImpl extends BaseFullTreeSnapshot implements In return { index: BigInt(minIndex), alreadyPresent: false }; } - findLeafIndex(value: Buffer): bigint | undefined { + override findLeafIndex(value: Buffer): bigint | undefined { const index = this.tree.findLeafIndex(value, false); if (index !== undefined && index < this.getNumLeaves()) { return index; diff --git a/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts b/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts index 75fb3a14a635..06d6d91f6c87 100644 --- a/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts +++ b/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts @@ -92,7 +92,7 @@ export class StandardIndexedTree extends TreeBase implements IndexedTree * @returns Empty promise. * @remarks Use batchInsert method instead. */ - appendLeaves(_leaves: Buffer[]): Promise { + override appendLeaves(_leaves: Buffer[]): Promise { throw new Error('Not implemented'); } @@ -100,7 +100,7 @@ export class StandardIndexedTree extends TreeBase implements IndexedTree * Commits the changes to the database. * @returns Empty promise. */ - public async commit(): Promise { + public override async commit(): Promise { await super.commit(); await this.commitLeaves(); } @@ -109,7 +109,7 @@ export class StandardIndexedTree extends TreeBase implements IndexedTree * Rolls back the not-yet-committed changes. * @returns Empty promise. */ - public async rollback(): Promise { + public override async rollback(): Promise { await super.rollback(); this.clearCachedLeaves(); } @@ -120,7 +120,7 @@ export class StandardIndexedTree extends TreeBase implements IndexedTree * @param includeUncommitted - Indicates whether to include uncommitted leaves in the computation. * @returns The value of the leaf at the given index or undefined if the leaf is empty. */ - public getLeafValue(index: bigint, includeUncommitted: boolean): Buffer | undefined { + public override getLeafValue(index: bigint, includeUncommitted: boolean): Buffer | undefined { const preimage = this.getLatestLeafPreimageCopy(index, includeUncommitted); return preimage && preimage.toBuffer(); } @@ -262,7 +262,7 @@ export class StandardIndexedTree extends TreeBase implements IndexedTree * 1024 leaves for the first block, because there's only neat space for 1023 leaves after 0. By padding with 1023 * more leaves, we can then insert the first block of 1024 leaves into indices 1024:2047. */ - public async init(prefilledSize: number): Promise { + public override async init(prefilledSize: number): Promise { if (prefilledSize < 1) { throw new Error(`Prefilled size must be at least 1!`); } diff --git a/yarn-project/merkle-tree/src/standard_indexed_tree/test/standard_indexed_tree_with_append.ts b/yarn-project/merkle-tree/src/standard_indexed_tree/test/standard_indexed_tree_with_append.ts index a772f1fc5fb3..0816f59edc5f 100644 --- a/yarn-project/merkle-tree/src/standard_indexed_tree/test/standard_indexed_tree_with_append.ts +++ b/yarn-project/merkle-tree/src/standard_indexed_tree/test/standard_indexed_tree_with_append.ts @@ -12,7 +12,7 @@ export class StandardIndexedTreeWithAppend extends StandardIndexedTree { * @returns Empty promise. * @remarks This method is inefficient and is here mostly for testing. Use batchInsert instead. */ - public appendLeaves(leaves: Buffer[]): Promise { + public override appendLeaves(leaves: Buffer[]): Promise { for (const leaf of leaves) { this.appendLeaf(leaf); } diff --git a/yarn-project/merkle-tree/src/standard_tree/standard_tree.ts b/yarn-project/merkle-tree/src/standard_tree/standard_tree.ts index ceb210e70948..27ce349a4844 100644 --- a/yarn-project/merkle-tree/src/standard_tree/standard_tree.ts +++ b/yarn-project/merkle-tree/src/standard_tree/standard_tree.ts @@ -18,7 +18,7 @@ export class StandardTree extends TreeBase imp * @param leaves - The leaves to append. * @returns Empty promise. */ - public appendLeaves(leaves: T[]): Promise { + public override appendLeaves(leaves: T[]): Promise { this.hasher.reset(); const timer = new Timer(); super.appendLeaves(leaves); diff --git a/yarn-project/merkle-tree/src/test/utils/pedersen_with_counter.ts b/yarn-project/merkle-tree/src/test/utils/pedersen_with_counter.ts index ff87702c8179..f5ab9af885a2 100644 --- a/yarn-project/merkle-tree/src/test/utils/pedersen_with_counter.ts +++ b/yarn-project/merkle-tree/src/test/utils/pedersen_with_counter.ts @@ -19,7 +19,7 @@ export class PedersenWithCounter extends Pedersen { * @deprecated Don't call pedersen directly in production code. Instead, create suitably-named functions for specific * purposes. */ - public hash(lhs: Uint8Array, rhs: Uint8Array): Buffer { + public override hash(lhs: Uint8Array, rhs: Uint8Array): Buffer { this.hashCounter++; return super.hash(lhs, rhs); } diff --git a/yarn-project/noir-compiler/package.json b/yarn-project/noir-compiler/package.json index 110a881ff8fd..c35f9e851d5f 100644 --- a/yarn-project/noir-compiler/package.json +++ b/yarn-project/noir-compiler/package.json @@ -58,6 +58,7 @@ "fs-extra": "^11.1.1", "lodash.camelcase": "^4.3.0", "lodash.capitalize": "^4.2.1", + "lodash.uniqby": "^4.7.0", "memfs": "^4.6.0", "pako": "^2.1.0", "semver": "^7.5.4", @@ -70,6 +71,7 @@ "@types/jest": "^29.5.0", "@types/lodash.camelcase": "^4.3.7", "@types/lodash.capitalize": "^4.2.7", + "@types/lodash.uniqby": "^4.7.9", "@types/node": "^18.7.23", "@types/pako": "^2.0.0", "@types/semver": "^7.5.4", diff --git a/yarn-project/noir-compiler/src/cli/add_noir_compiler_commander_actions.ts b/yarn-project/noir-compiler/src/cli/add_noir_compiler_commander_actions.ts index 02fa9eb6c0bb..a3330b8368f7 100644 --- a/yarn-project/noir-compiler/src/cli/add_noir_compiler_commander_actions.ts +++ b/yarn-project/noir-compiler/src/cli/add_noir_compiler_commander_actions.ts @@ -12,15 +12,10 @@ export function addCodegenCommanderAction(program: Command, _: LogFn = () => {}) .command('codegen') .argument('', 'Path to the Noir ABI or project dir.') .option('-o, --outdir ', 'Output folder for the generated code.') - .option('--ts', 'Generate TypeScript wrapper.') - .option('--nr', 'Generate Noir interface.') .option('--force', 'Force code generation even when the contract has not changed.') .description('Validates and generates an Aztec Contract ABI from Noir ABI.') - .action(async (noirAbiPath: string, { outdir, ts, nr, force }) => { - if (ts && nr) { - throw new Error('--ts and --nr are mutually exclusive.'); - } + .action(async (noirAbiPath: string, { outdir, force }) => { const { generateCode } = await import('./codegen.js'); - generateCode(outdir || dirname(noirAbiPath), noirAbiPath, { ts, nr, force }); + generateCode(outdir || dirname(noirAbiPath), noirAbiPath, { force }); }); } diff --git a/yarn-project/noir-compiler/src/cli/codegen.ts b/yarn-project/noir-compiler/src/cli/codegen.ts index 47aaeaa390ba..858109a982b1 100644 --- a/yarn-project/noir-compiler/src/cli/codegen.ts +++ b/yarn-project/noir-compiler/src/cli/codegen.ts @@ -5,14 +5,13 @@ import crypto from 'crypto'; import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'fs'; import path from 'path'; -import { generateNoirContractInterface } from '../contract-interface-gen/noir.js'; import { generateTypescriptContractInterface } from '../contract-interface-gen/typescript.js'; const cacheFilePath = './codegenCache.json'; let cache: Record = {}; /** Generate code options */ -type GenerateCodeOptions = { /** Typescript */ ts?: boolean; /** Noir */ nr?: boolean; force?: boolean }; +type GenerateCodeOptions = { force?: boolean }; /** * Generates Noir interface or Typescript interface for a folder or single file from a Noir compilation artifact. @@ -49,26 +48,18 @@ function generateFromNoirAbi(outputPath: string, noirAbiPath: string, opts: Gene const contract = JSON.parse(readFileSync(noirAbiPath, 'utf8')); const aztecAbi = loadContractArtifact(contract); - const { nr, ts } = opts; mkdirSync(outputPath, { recursive: true }); - if (nr) { - const noirContract = generateNoirContractInterface(aztecAbi); - writeFileSync(`${outputPath}/${aztecAbi.name}.nr`, noirContract); - return; + let relativeArtifactPath = path.relative(outputPath, noirAbiPath); + if (relativeArtifactPath === path.basename(noirAbiPath)) { + // Prepend ./ for local import if the folder is the same + relativeArtifactPath = `./${relativeArtifactPath}`; } - if (ts) { - let relativeArtifactPath = path.relative(outputPath, noirAbiPath); - if (relativeArtifactPath === path.basename(noirAbiPath)) { - // Prepend ./ for local import if the folder is the same - relativeArtifactPath = `./${relativeArtifactPath}`; - } + const tsWrapper = generateTypescriptContractInterface(aztecAbi, relativeArtifactPath); + writeFileSync(`${outputPath}/${aztecAbi.name}.ts`, tsWrapper); - const tsWrapper = generateTypescriptContractInterface(aztecAbi, relativeArtifactPath); - writeFileSync(`${outputPath}/${aztecAbi.name}.ts`, tsWrapper); - } updateCache(contractName, currentHash); } diff --git a/yarn-project/noir-compiler/src/contract-interface-gen/noir.ts b/yarn-project/noir-compiler/src/contract-interface-gen/noir.ts deleted file mode 100644 index 52fd07889734..000000000000 --- a/yarn-project/noir-compiler/src/contract-interface-gen/noir.ts +++ /dev/null @@ -1,308 +0,0 @@ -import { - type ABIParameter, - type ABIVariable, - type ContractArtifact, - type FunctionArtifact, - FunctionSelector, - FunctionType, - type StructType, -} from '@aztec/foundation/abi'; -import { times } from '@aztec/foundation/collection'; - -import camelCase from 'lodash.camelcase'; -import capitalize from 'lodash.capitalize'; - -/** - * Returns whether this function type corresponds to a private call. - * @param functionType - The function type. - * @returns Whether this function type corresponds to a private call. - */ -function isPrivateCall(functionType: FunctionType) { - return functionType === FunctionType.SECRET; -} - -/** - * Generates a call to a private function using the context. - * @param selector - The selector of a function. - * @param functionType - Type of the function. - * @returns A code string. - */ -function generateCallStatement( - selector: FunctionSelector, - functionType: FunctionType, - callingContext: 'private' | 'public', -) { - const callMethod = isPrivateCall(functionType) ? 'call_private_function' : 'call_public_function'; - const args = [ - 'self.address', - `FunctionSelector::from_field(${selector.toString()})`, - 'serialized_args', - ...(callingContext === 'private' ? [] : ['GasOpts::default()']), - ]; - return ` - context.${callMethod}(${args.join(', ')})`; -} - -/** - * Formats a string as pascal case. - * @param str - A string. - * @returns A capitalized camelcase string. - */ -function toPascalCase(str: string) { - const camel = camelCase(str); - return camel[0].toUpperCase() + camel.slice(1); -} - -/** - * Returns a struct name given a list of fragments. - * @param fragments - Fragments. - * @returns The concatenation of the capitalized fragments. - */ -function getStructName(...fragments: string[]) { - return fragments.map(toPascalCase).join('') + 'Struct'; -} - -/** - * Returns a Noir type name for the given ABI variable. - * @param param - ABI variable to translate to a Noir type name. - * @param parentNames - Function name or parent structs or arrays to use for struct qualified names. - * @returns A valid Noir basic type name or a name for a struct. - */ -function getTypeName(param: ABIVariable, ...parentNames: string[]): string { - const type = param.type; - switch (type.kind) { - case 'field': - return 'Field'; - case 'boolean': - return 'bool'; - case 'integer': - return `${type.sign === 'signed' ? 'i' : 'u'}${type.width}`; - case 'string': - throw new Error(`Strings not supported yet`); - case 'array': - return `[${getTypeName({ name: param.name, type: type.type }, ...parentNames)};${type.length}]`; - case 'struct': - return getStructName(param.name, ...parentNames); - default: - throw new Error(`Unknown type ${type}`); - } -} - -/** - * Generates a parameter string. - * @param param - ABI parameter. - * @param functionData - Parent function. - * @returns A Noir string with the param name and type to be used in a function call. - */ -function generateParameter(param: ABIParameter, functionData: FunctionArtifact) { - const typename = getTypeName(param, functionData.name); - return `${param.name}: ${typename}`; -} - -/** - * Collects all parameters for a given function and flattens them according to how they should be serialized. - * @param parameters - Parameters for a function. - * @returns List of parameters flattened to basic data types. - */ -function collectParametersForSerialization(parameters: ABIVariable[]) { - const flattened: string[] = []; - for (const parameter of parameters) { - const { name } = parameter; - if (parameter.type.kind === 'array') { - const nestedType = parameter.type.type; - const nested = times(parameter.type.length, i => - collectParametersForSerialization([{ name: `${name}[${i}]`, type: nestedType }]), - ); - flattened.push(...nested.flat()); - } else if (parameter.type.kind === 'struct') { - const nested = parameter.type.fields.map(field => - collectParametersForSerialization([{ name: `${name}.${field.name}`, type: field.type }]), - ); - flattened.push(...nested.flat()); - } else if (parameter.type.kind === 'string') { - throw new Error(`String not yet supported`); - } else if (parameter.type.kind === 'field') { - flattened.push(name); - } else { - flattened.push(`${name} as Field`); - } - } - return flattened; -} - -/** - * Generates Noir code for serializing the parameters into an array of fields. - * @param parameters - Parameters to serialize. - * @returns The serialization code. - */ -function generateSerialization(parameters: ABIParameter[]) { - const flattened = collectParametersForSerialization(parameters); - const declaration = ` let mut serialized_args = [0; ${flattened.length}];`; - const lines = flattened.map((param, i) => ` serialized_args[${i}] = ${param};`); - return [declaration, ...lines].join('\n'); -} - -/** - * Generate a function interface for a particular function of the Aztec.nr Contract being processed. This function will be a method of the ContractInterface struct being created here. - * @param functionData - Data relating to the function, which can be used to generate a callable Aztec.nr Function. - * @param kind - Whether this interface will be used from private or public functions. - * @returns A code string. - */ -function generateFunctionInterface(functionData: FunctionArtifact, kind: 'private' | 'public') { - const { name, parameters } = functionData; - const selector = FunctionSelector.fromNameAndParameters(name, parameters); - const serialization = generateSerialization(parameters); - const contextType = kind === 'private' ? '&mut PrivateContext' : '&mut PublicContext'; - const callStatement = generateCallStatement(selector, functionData.functionType, kind); - const allParams = ['self', `context: ${contextType}`, ...parameters.map(p => generateParameter(p, functionData))]; - const isPrivate = isPrivateCall(functionData.functionType); - const isSync = (isPrivate && kind === 'private') || (!isPrivate && kind === 'public'); - // TODO: When return typing data is available in the artifact, we can instead codegen the concrete return type for public and private. - const generics = !isPrivate && isSync ? `` : ``; - const retType = isPrivate ? `-> PackedReturns` : isSync ? `-> FunctionReturns ` : ``; - - return ` - pub fn ${name}${generics}( - ${allParams.join(',\n ')} - ) ${retType}{ -${serialization} -${callStatement} - } - `; -} - -/** - * Generates static imports. - * @returns A string of code which will be needed in every contract interface, regardless of the contract. - */ -function generateStaticImports() { - return `use dep::std; -use dep::aztec::context::{ PrivateContext, PublicContext, PackedReturns, FunctionReturns, gas::GasOpts }; -use dep::aztec::protocol_types::{ - address::AztecAddress, - abis::function_selector::FunctionSelector, -};`; -} - -/** - * Generates the name of the contract struct, based on whether it's for private or public usage. - * @param contractName - Name of the contract. - * @param kind - Whether this interface will be used from private or public functions. - * @returns A name. - */ -function generateContractStructName(contractName: string, kind: 'private' | 'public') { - return `${contractName}${capitalize(kind)}ContextInterface`; -} - -/** - * Generate the main focus of this code generator: the contract interface struct. - * @param contractName - the name of the contract, as matches the original source file. - * @param kind - Whether this interface will be used from private or public functions. - * @returns Code. - */ -function generateContractInterfaceStruct(contractName: string, kind: 'private' | 'public') { - return `// Interface for calling ${contractName} functions from a ${kind} context -struct ${generateContractStructName(contractName, kind)} { - address: AztecAddress, -} -`; -} - -/** - * Generates the implementation of the contract interface struct. - * @param contractName - The name of the contract, as matches the original source file. - * @param kind - Whether this interface will be used from private or public functions. - * @param functions - An array of strings, where each string is valid Noir code describing the function interface of one of the contract's functions (as generated via `generateFunctionInterface` above). - * @returns Code. - */ -function generateContractInterfaceImpl(contractName: string, kind: 'private' | 'public', functions: string[]) { - return `impl ${generateContractStructName(contractName, kind)} { - pub fn at(address: AztecAddress) -> Self { - Self { - address, - } - } - ${functions.join('\n')} -} -`; -} - -/** Represents a struct along its parent names to derive a fully qualified name. */ -type StructInfo = ABIVariable & { /** Parent name */ parentNames: string[] }; - -/** - * Generates a Noir struct. - * @param struct - Struct info. - * @returns Code representing the struct. - */ -function generateStruct(struct: StructInfo) { - const fields = (struct.type as StructType).fields.map( - field => ` ${field.name}: ${getTypeName(field, struct.name, ...struct.parentNames)},`, - ); - - return ` -struct ${getStructName(struct.name, ...struct.parentNames)} { -${fields.join('\n')} -}`; -} - -/** - * Collects all structs across all parameters. - * @param params - Parameters to look for structs, either structs themselves or nested. - * @param parentNames - Parent names to derive fully qualified names when needed. - * @returns A list of struct infos. - */ -function collectStructs(params: ABIVariable[], parentNames: string[]): StructInfo[] { - const structs: StructInfo[] = []; - for (const param of params) { - if (param.type.kind === 'struct') { - const struct = { ...param, parentNames }; - structs.push(struct, ...collectStructs(param.type.fields, [param.name, ...parentNames])); - } else if (param.type.kind === 'array') { - structs.push(...collectStructs([{ name: param.name, type: param.type.type }], [...parentNames])); - } - } - return structs; -} - -/** - * Generates the struct definition and implementation for a contract interface. - * @param abiName - Name of the contract. - * @param kind - Whether this interface will be used from private or public functions. - * @param methods - Contract methods to generate (private ones will be excluded if kind is public) - * @returns Code. - */ -function generateContractStruct(abiName: string, kind: 'private' | 'public', methods: FunctionArtifact[]) { - const contractStruct: string = generateContractInterfaceStruct(abiName, kind); - const applicableMethods = methods.filter(m => kind === 'private' || !isPrivateCall(m.functionType)); - const functionInterfaces = applicableMethods.map(m => generateFunctionInterface(m, kind)); - const contractImpl: string = generateContractInterfaceImpl(abiName, kind, functionInterfaces); - - return ` -${contractStruct} -${contractImpl} - `; -} - -/** - * Generates the Noir code to represent an interface for calling a contract. - * @param artifact - The compiled Aztec.nr artifact. - * @returns The corresponding ts code. - */ -export function generateNoirContractInterface(artifact: ContractArtifact) { - // We don't allow calling internal fns or unconstrained fns from other contracts - const methods = artifact.functions.filter(f => !f.isInternal && f.functionType !== FunctionType.UNCONSTRAINED); - const paramStructs = methods.flatMap(m => collectStructs(m.parameters, [m.name])).map(generateStruct); - const privateContractStruct = generateContractStruct(artifact.name, 'private', methods); - const publicContractStruct = generateContractStruct(artifact.name, 'public', methods); - - return `/* Autogenerated file, do not edit! */ - -${generateStaticImports()} -${paramStructs.join('\n')} - -${privateContractStruct} - -${publicContractStruct} -`; -} diff --git a/yarn-project/noir-compiler/src/contract-interface-gen/typescript.ts b/yarn-project/noir-compiler/src/contract-interface-gen/typescript.ts index da5e9cd6e8fe..04f1af32ed49 100644 --- a/yarn-project/noir-compiler/src/contract-interface-gen/typescript.ts +++ b/yarn-project/noir-compiler/src/contract-interface-gen/typescript.ts @@ -14,6 +14,8 @@ import { isWrappedFieldStruct, } from '@aztec/foundation/abi'; +import uniqBy from 'lodash.uniqby'; + /** * Returns the corresponding typescript type for a given Noir type. * @param type - The input Noir type. @@ -224,7 +226,9 @@ function generateStorageLayoutGetter(input: ContractArtifact) { * @param input - The contract artifact. */ function generateNotesGetter(input: ContractArtifact) { - const notes = input.outputs.globals.notes ? (input.outputs.globals.notes as TupleValue[]) : []; + const notes = input.outputs.globals.notes + ? uniqBy(input.outputs.globals.notes as TupleValue[], n => (n.fields[1] as BasicValue<'string', string>).value) + : []; const notesUnionType = notes.map(n => `'${(n.fields[1] as BasicValue<'string', string>).value}'`).join(' | '); const noteMetadata = notes @@ -312,7 +316,7 @@ export class ${input.name}Contract extends ContractBase { ${notesGetter} /** Type-safe wrappers for the public methods exposed by the contract. */ - public methods!: { + public override methods!: { ${methods.join('\n')} }; } diff --git a/yarn-project/noir-compiler/src/index.ts b/yarn-project/noir-compiler/src/index.ts index a28e4f093031..c6c4a84e4412 100644 --- a/yarn-project/noir-compiler/src/index.ts +++ b/yarn-project/noir-compiler/src/index.ts @@ -1,2 +1 @@ export { generateTypescriptContractInterface } from './contract-interface-gen/typescript.js'; -export { generateNoirContractInterface } from './contract-interface-gen/noir.js'; diff --git a/yarn-project/noir-contracts.js/scripts/generate-noir-interfaces.sh b/yarn-project/noir-contracts.js/scripts/generate-noir-interfaces.sh deleted file mode 100755 index 249d168242f0..000000000000 --- a/yarn-project/noir-contracts.js/scripts/generate-noir-interfaces.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -CONTRACTS=( - test_contract-Test -) - -NOIR_CONTRACTS_DIR="../../noir-projects/noir-contracts" - -for contract in $CONTRACTS; do - echo "Generating Noir interface for $contract" - OUT_DIR="$NOIR_CONTRACTS_DIR/contracts/${contract%%-*}/src" - node --no-warnings ../noir-compiler/dest/cli.js codegen -o $OUT_DIR --nr --force $NOIR_CONTRACTS_DIR/target/$contract.json - mv $OUT_DIR/${contract#*-}.nr $OUT_DIR/interface.nr -done - -echo "Done updating Noir interfaces" \ No newline at end of file diff --git a/yarn-project/noir-contracts.js/scripts/generate-types.sh b/yarn-project/noir-contracts.js/scripts/generate-types.sh index 87a13d3459df..6e98b09125b6 100755 --- a/yarn-project/noir-contracts.js/scripts/generate-types.sh +++ b/yarn-project/noir-contracts.js/scripts/generate-types.sh @@ -28,7 +28,7 @@ for ABI in $(find ../../noir-projects/noir-contracts/target -maxdepth 1 -type f done # Generate types for the contracts -node --no-warnings ../noir-compiler/dest/cli.js codegen -o $OUT_DIR --ts artifacts +node --no-warnings ../noir-compiler/dest/cli.js codegen -o $OUT_DIR artifacts # Append exports for each generated TypeScript file to index.ts find "$OUT_DIR" -maxdepth 1 -type f -name '*.ts' ! -name 'index.ts' | while read -r TS_FILE; do diff --git a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap deleted file mode 100644 index 67fdd01c8720..000000000000 --- a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap +++ /dev/null @@ -1,2100 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Private kernel Executes private kernel inner for a nested call 1`] = ` -PrivateKernelCircuitPublicInputs { - "aggregationObject": AggregationObject { - "hasData": false, - "p0": G1AffineElement { - "x": Fq<0x0000000000000000000000000000000000000000000000000000000000000001>, - "y": Fq<0x0000000000000000000000000000000000000000000000000000000000000002>, - }, - "p1": G1AffineElement { - "x": Fq<0x0000000000000000000000000000000000000000000000000000000000000001>, - "y": Fq<0x0000000000000000000000000000000000000000000000000000000000000002>, - }, - "proofWitnessIndices": [ - 3027, - 3028, - 3029, - 3030, - 3031, - 3032, - 3033, - 3034, - 3035, - 3036, - 3037, - 3038, - 3039, - 3040, - 3041, - 3042, - ], - "publicInputs": [], - }, - "constants": CombinedConstantData { - "gasSettings": GasSettings { - "da": DimensionGasSettings { - "gasLimit": 0, - "maxFeePerGas": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "teardownGasLimit": 0, - }, - "inclusionFee": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "l1": DimensionGasSettings { - "gasLimit": 0, - "maxFeePerGas": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "teardownGasLimit": 0, - }, - "l2": DimensionGasSettings { - "gasLimit": 0, - "maxFeePerGas": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "teardownGasLimit": 0, - }, - }, - "historicalHeader": Header { - "contentCommitment": ContentCommitment { - "inHash": Buffer<0x00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c>, - "outHash": Buffer<0x0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c3>, - "txTreeHeight": Fr<0x0000000000000000000000000000000000000000000000000000000000000001>, - "txsEffectsHash": Buffer<0x001b4dbaea2f9d80e6cb122cdaee2739150556b9e0c0a90709f6d5cbce342c1a>, - }, - "globalVariables": { - "blockNumber": "0x0000000000000000000000000000000000000000000000000000000000000003", - "chainId": "0x0000000000000000000000000000000000000000000000000000000000007a69", - "coinbase": "0x0000000000000000000000000000000000000000", - "feeRecipient": "0x0000000000000000000000000000000000000000000000000000000000000000", - "gasFees": { - "feePerDaGas": "0x0000000000000000000000000000000000000000000000000000000000000000", - "feePerL1Gas": "0x0000000000000000000000000000000000000000000000000000000000000000", - "feePerL2Gas": "0x0000000000000000000000000000000000000000000000000000000000000000", - }, - "timestamp": "0x0000000000000000000000000000000000000000000000000000000066171575", - "version": "0x0000000000000000000000000000000000000000000000000000000000000001", - }, - "lastArchive": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 3, - "root": Fr<0x1ba288b53571e664cfa3bfefb89ab6191de95673e41d1fb22e62b09b855d67f7>, - }, - "state": StateReference { - "l1ToL2MessageTree": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 48, - "root": Fr<0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80>, - }, - "partial": PartialStateReference { - "noteHashTree": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 384, - "root": Fr<0x2f1cfd44c9cba4e480325d4fd884081ed1c4dd05261d6ca155a74c412a52cc1b>, - }, - "nullifierTree": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 512, - "root": Fr<0x304ac7a8f67dbec9f24638c7a0b6a41908a73d0ab95af4a8e0508930a7b5c7e9>, - }, - "publicDataTree": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 256, - "root": Fr<0x0572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b>, - }, - }, - }, - }, - "txContext": TxContext { - "chainId": Fr<0x0000000000000000000000000000000000000000000000000000000000007a69>, - "isFeePaymentTx": false, - "isRebatePaymentTx": false, - "version": Fr<0x0000000000000000000000000000000000000000000000000000000000000001>, - }, - }, - "end": PrivateAccumulatedData { - "encryptedLogPreimagesLength": Fr<0x000000000000000000000000000000000000000000000000000000000000000c>, - "encryptedLogsHash": Fr<0x00f33ae280239814c4dfaaafc16fc138a8d3eae52bb962af6576cbb61c2af246>, - "gasUsed": GasUsed { - "daGas": 0, - "l1Gas": 0, - "l2Gas": 0, - }, - "newL2ToL1Msgs": [ - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - ], - "newNoteHashes": [ - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "newNullifiers": [ - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x21d1d4076140e83671eecc82ab096e1cd02e4473ecfe72a9aa0b6f4f385a1431>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "privateCallStack": [ - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "publicCallStack": [ - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "unencryptedLogPreimagesLength": Fr<0x000000000000000000000000000000000000000000000000000000000000000c>, - "unencryptedLogsHash": Fr<0x00f33ae280239814c4dfaaafc16fc138a8d3eae52bb962af6576cbb61c2af246>, - }, - "minRevertibleSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000002>, - "validationRequests": ValidationRequests { - "forRollup": RollupValidationRequests { - "maxBlockNumber": MaxBlockNumber { - "isSome": false, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - }, - "noteHashReadRequests": [ - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "nullifierKeyValidationRequests": [ - NullifierKeyValidationRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "publicKey": Point { - "kind": "point", - "x": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "y": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "secretKey": Fq<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - NullifierKeyValidationRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "publicKey": Point { - "kind": "point", - "x": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "y": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "secretKey": Fq<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - NullifierKeyValidationRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "publicKey": Point { - "kind": "point", - "x": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "y": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "secretKey": Fq<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - NullifierKeyValidationRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "publicKey": Point { - "kind": "point", - "x": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "y": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "secretKey": Fq<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "nullifierNonExistentReadRequests": [ - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "nullifierReadRequests": [ - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ReadRequestContext { - "contractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "counter": 0, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "publicDataReads": [ - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - PublicDataRead { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - }, -} -`; - -exports[`Private kernel Executes private kernel ordering after a deployment 1`] = ` -PrivateKernelTailCircuitPublicInputs { - "aggregationObject": AggregationObject { - "hasData": false, - "p0": G1AffineElement { - "x": Fq<0x0000000000000000000000000000000000000000000000000000000000000001>, - "y": Fq<0x0000000000000000000000000000000000000000000000000000000000000002>, - }, - "p1": G1AffineElement { - "x": Fq<0x0000000000000000000000000000000000000000000000000000000000000001>, - "y": Fq<0x0000000000000000000000000000000000000000000000000000000000000002>, - }, - "proofWitnessIndices": [ - 3027, - 3028, - 3029, - 3030, - 3031, - 3032, - 3033, - 3034, - 3035, - 3036, - 3037, - 3038, - 3039, - 3040, - 3041, - 3042, - ], - "publicInputs": [], - }, - "constants": CombinedConstantData { - "gasSettings": GasSettings { - "da": DimensionGasSettings { - "gasLimit": 0, - "maxFeePerGas": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "teardownGasLimit": 0, - }, - "inclusionFee": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "l1": DimensionGasSettings { - "gasLimit": 0, - "maxFeePerGas": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "teardownGasLimit": 0, - }, - "l2": DimensionGasSettings { - "gasLimit": 0, - "maxFeePerGas": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "teardownGasLimit": 0, - }, - }, - "historicalHeader": Header { - "contentCommitment": ContentCommitment { - "inHash": Buffer<0x0000000000000000000000000000000000000000000000000000000000000000>, - "outHash": Buffer<0x0000000000000000000000000000000000000000000000000000000000000000>, - "txTreeHeight": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "txsEffectsHash": Buffer<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "globalVariables": { - "blockNumber": "0x0000000000000000000000000000000000000000000000000000000000000000", - "chainId": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "feeRecipient": "0x0000000000000000000000000000000000000000000000000000000000000000", - "gasFees": { - "feePerDaGas": "0x0000000000000000000000000000000000000000000000000000000000000000", - "feePerL1Gas": "0x0000000000000000000000000000000000000000000000000000000000000000", - "feePerL2Gas": "0x0000000000000000000000000000000000000000000000000000000000000000", - }, - "timestamp": "0x0000000000000000000000000000000000000000000000000000000000000000", - "version": "0x0000000000000000000000000000000000000000000000000000000000000000", - }, - "lastArchive": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 0, - "root": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - "state": StateReference { - "l1ToL2MessageTree": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 0, - "root": Fr<0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80>, - }, - "partial": PartialStateReference { - "noteHashTree": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 0, - "root": Fr<0x16642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb>, - }, - "nullifierTree": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 128, - "root": Fr<0x0bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278>, - }, - "publicDataTree": AppendOnlyTreeSnapshot { - "nextAvailableLeafIndex": 64, - "root": Fr<0x0572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b>, - }, - }, - }, - }, - "txContext": TxContext { - "chainId": Fr<0x0000000000000000000000000000000000000000000000000000000000007a69>, - "isFeePaymentTx": false, - "isRebatePaymentTx": false, - "version": Fr<0x0000000000000000000000000000000000000000000000000000000000000001>, - }, - }, - "forPublic": undefined, - "forRollup": PartialPrivateTailPublicInputsForRollup { - "end": CombinedAccumulatedData { - "encryptedLogPreimagesLength": Fr<0x000000000000000000000000000000000000000000000000000000000000013c>, - "encryptedLogsHash": Fr<0x00d9390f71f6e9a79785314dbe71198e95418c404086825f7b33a1cecd7e0a16>, - "gasUsed": GasUsed { - "daGas": 0, - "l1Gas": 0, - "l2Gas": 0, - }, - "newL2ToL1Msgs": [ - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - ], - "newNoteHashes": [ - Fr<0x14e797216d66e4e470a0f73e890ef6607f43bdb4897f1f2cddcfa3ad8744f092>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - ], - "newNullifiers": [ - Fr<0x2984d86a49ea3553c56bad2dbb7151399a5ef4281892e2b881ea7701ee178c43>, - Fr<0x2f3714e42ab151d853ce688205234d6f7531a931255da3c015d0066839bd8baf>, - Fr<0x00980df506642279a35f8211f10abbb31491b7dcdcc194aa9da7f7d484703269>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - ], - "publicDataUpdateRequests": [ - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - ], - "unencryptedLogPreimagesLength": Fr<0x0000000000000000000000000000000000000000000000000000000000000008>, - "unencryptedLogsHash": Fr<0x008d4d695766a616808caa331119da14269ac3271c251dec3a11df896131ba2c>, - }, - "rollupValidationRequests": RollupValidationRequests { - "maxBlockNumber": MaxBlockNumber { - "isSome": false, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - }, - }, - "revertCode": RevertCode { - "code": 0, - }, -} -`; diff --git a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-init.hex b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-init.hex index 82267eac885d..35212bb487c5 100644 --- a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-init.hex +++ b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-init.hex @@ -1 +1 @@ -12f3878234dbd892f874b0b1e7ecfa981192df2082674a462f2030cd42940c3d37889ba101058ad91eb9f5e062fd8d238f47fa206ecdba2dd667fde55fe75cc6b41d0a481f00000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000112f3878234dbd892f874b0b1e7ecfa981192df2082674a462f2030cd42940c3d37889ba101000000000000000000000000000000000000000000000000000000000000000012f3878234dbd892f874b0b1e7ecfa981192df2082674a462f2030cd42940c3d000000000000000000000000000000000000000037889ba100000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058ad91eb9f5e062fd8d238f47fa206ecdba2dd667fde55fe75cc6b41d0a481f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005016ee1170a01e7f9340076e89ad1dfd299c888cd2d1af0a33161a83f8f2064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b800e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000105016ee1170a01e7f9340076e89ad1dfd299c888cd2d1af0a33161a83f8f206412f3878234dbd892f874b0b1e7ecfa981192df2082674a462f2030cd42940c3d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f28729113b48351481d85220366c267713c6bf17ab3437fd04d59b6c6dc1bc98f1dae27cc7fe2af345f160253be3875d449a7e9ba6bd68747d87d4e7054b8111527b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed19ffad41d477b4d4077d3edfe7eaf592f3b332d915dc68b41f2f1f370ebed632000000000000000000000000000000000000000000000000000000000000000027b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed21dbfd1d029bf447152fcf89e355c334610d1632436ba170f738107266a715500bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +1166f8313bdcd368a148663939fd38eb6a6500a577435b5a433ff0357ca8b15937889ba10104fe385bb1c80a41d917a6f6061312dc211638616c9da820eb5bca522bc8996500000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000011166f8313bdcd368a148663939fd38eb6a6500a577435b5a433ff0357ca8b15937889ba10100000000000000000000000000000000000000000000000000000000000000001166f8313bdcd368a148663939fd38eb6a6500a577435b5a433ff0357ca8b159000000000000000000000000000000000000000037889ba135a4e90035a4e90035a4e9000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000004fe385bb1c80a41d917a6f6061312dc211638616c9da820eb5bca522bc89965000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001019e4c3aa9b03aa5bf974d1954b5e219db2b0e1d42a4ed9f095c102eb2157d7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000011019e4c3aa9b03aa5bf974d1954b5e219db2b0e1d42a4ed9f095c102eb2157d71166f8313bdcd368a148663939fd38eb6a6500a577435b5a433ff0357ca8b15900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f1568448ac2259bbec7694d6670a15177bd0304d71700aa7fea107740a077d0411dae27cc7fe2af345f160253be3875d449a7e9ba6bd68747d87d4e7054b8111527b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed19ffad41d477b4d4077d3edfe7eaf592f3b332d915dc68b41f2f1f370ebed632000000000000000000000000000000000000000000000000000000000000000027b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed21dbfd1d029bf447152fcf89e355c334610d1632436ba170f738107266a715500bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-inner.hex b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-inner.hex index 34510a76e1b2..3b12c7db785b 100644 --- a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-inner.hex +++ b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-inner.hex @@ -1 +1 @@ -0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be200000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021d1d4076140e83671eecc82ab096e1cd02e4473ecfe72a9aa0b6f4f385a14310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d4d695766a616808caa331119da14269ac3271c251dec3a11df896131ba2c008d4d695766a616808caa331119da14269ac3271c251dec3a11df896131ba2c00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008160676423f42e941d3690819833afecb0168c3ccde3e22656def19177297942a2a9134b767b685adbef84868a5b3883643838e479838406e6e6f35f77fad416100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ba288b53571e664cfa3bfefb89ab6191de95673e41d1fb22e62b09b855d67f7000000030000000000000000000000000000000000000000000000000000000000000001001b4dbaea2f9d80e6cb122cdaee2739150556b9e0c0a90709f6d5cbce342c1a00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000302f1cfd44c9cba4e480325d4fd884081ed1c4dd05261d6ca155a74c412a52cc1b00000180304ac7a8f67dbec9f24638c7a0b6a41908a73d0ab95af4a8e0508930a7b5c7e9000002000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000001000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000661715750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000001beef249a9a8a9cf54420d99e988b97d29ed03f795b42c12bf3eff8ae366fdde2ac527c2b45a8c7039889bdea861709348fe021ff609b3c08527b4ffc4388952211dad326c6282e200184455c579d625cc17f01278e0811db2b9515085b1cc6f06b646bebd48b22cab44919afa5822d87cdeb6eb3c81410c944a0c91948e84c80906bca1012a9134b767b685adbef84868a5b3883643838e479838406e6e6f35f77fad416106b646bebd48b22cab44919afa5822d87cdeb6eb3c81410c944a0c91948e84c800000000000000000000000000000000000000000906bca1000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002898402da2fa95f47c47763fe5b171ff3155bd31e5af88d9823bccb26b6701542451ab56341b4067780469e41818b47f8fd45f4bd186f22ba4b4a1bb5d45a42d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000300e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b800e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000041ba288b53571e664cfa3bfefb89ab6191de95673e41d1fb22e62b09b855d67f7000000030000000000000000000000000000000000000000000000000000000000000001001b4dbaea2f9d80e6cb122cdaee2739150556b9e0c0a90709f6d5cbce342c1a00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000302f1cfd44c9cba4e480325d4fd884081ed1c4dd05261d6ca155a74c412a52cc1b00000180304ac7a8f67dbec9f24638c7a0b6a41908a73d0ab95af4a8e0508930a7b5c7e9000002000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000001000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000066171575000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f1e2f8a2c647f01b125bd299928e4cb2027e20922fa89a973a6bc1913790d84e81eda71eb7011cc398d393d8a083a784961615c243559c964511a6f6a18a12d9427b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed0669ad6620a19c0ff5f912c2970e504ddc8cdf586eafe27ab44345840c9dca8200000000000000000000000000000000000000000000000000000000000000002452a14c748981acff167dba9088770b6c2c2dc34677295a1974f2c247236ba11e904e4d0a67667f8faaa89198f5e89684e213bc99a83c3b20888d5854d3dd320bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be20000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001cbfe3e489299947cef42ee1812ff6b238b856ae13f95437b82ce86f44fe4fb600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008184e3ae016e6a45c309f1d04c50823f260cc02e2f4b5c9d8bf7cd10d8dc1c6e3304faeaac4852e3721a5f76646d8f1bcf4e1cf8e6f4795a6a0053d7540aff67900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eed5cdbaafbbc794dbfae12e568d38ba22a9c222066df87fd213f7c5240117e000000030000000000000000000000000000000000000000000000000000000000000001007710847c110c9d1d2feb57e05a986dfb30c2d33811a9d05c76c9657af34d0700089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f8000000030234676c856daf7c0bf73f0e9a3980387c0a78cceb1be03d3b9542ad31ebfa1d80000018000d1d7b14ec97e9e3332c3eb5734202d6e3a0c76b3a7de8a05a857d7c885ae0e000002000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000001000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000661e94db0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f0000000020a37986ee9aa91cfe3a609b350e6d266999461b635ca0420b884b08d50f4d1009c5c0728c89546b73fe3b9aa402e0ae562ce934b88235b388c690e5b0f20e8218cae2fa2e3faf92d1536361e486b34baad26a22d1253b821563a5a1003b20df15d54e8dde4393f502819821390cfd31ba0c912e86fbc2da32922256c53255f60906bca101304faeaac4852e3721a5f76646d8f1bcf4e1cf8e6f4795a6a0053d7540aff67915d54e8dde4393f502819821390cfd31ba0c912e86fbc2da32922256c53255f600000000000000000000000000000000000000000906bca135a4e90035a4e90035a4e9000000000000033b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e1000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000002898402da2fa95f47c47763fe5b171ff3155bd31e5af88d9823bccb26b6701542451ab56341b4067780469e41818b47f8fd45f4bd186f22ba4b4a1bb5d45a42d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040eed5cdbaafbbc794dbfae12e568d38ba22a9c222066df87fd213f7c5240117e000000030000000000000000000000000000000000000000000000000000000000000001007710847c110c9d1d2feb57e05a986dfb30c2d33811a9d05c76c9657af34d0700089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f8000000030234676c856daf7c0bf73f0e9a3980387c0a78cceb1be03d3b9542ad31ebfa1d80000018000d1d7b14ec97e9e3332c3eb5734202d6e3a0c76b3a7de8a05a857d7c885ae0e000002000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000001000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000661e94db000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f0de7a2fe9b5384b7142877d9ee77fb5bf7073902e711504a1ec4c7039b3ba35b2904908a7e8e4b61c07ee8c119b09ca8dc00cc6787e3dc5c4100c845d94b19cc27b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed0ad428a44324ce02cf0c67cb517de63f73072ab8ab5295a9c1f394057bc9719500000000000000000000000000000000000000000000000000000000000000002452a14c748981acff167dba9088770b6c2c2dc34677295a1974f2c247236ba11e904e4d0a67667f8faaa89198f5e89684e213bc99a83c3b20888d5854d3dd320bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-ordering.hex b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-ordering.hex index 397f119d3159..157f363bcb6c 100644 --- a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-ordering.hex +++ b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-ordering.hex @@ -1 +1 @@ -0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b264fb6b25be47ab08630d45172a9b9c20b526ed449e50267897acb9bd133c900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002984d86a49ea3553c56bad2dbb7151399a5ef4281892e2b881ea7701ee178c43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f3714e42ab151d853ce688205234d6f7531a931255da3c015d0066839bd8baf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100980df506642279a35f8211f10abbb31491b7dcdcc194aa9da7f7d484703269000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d9390f71f6e9a79785314dbe71198e95418c404086825f7b33a1cecd7e0a16008d4d695766a616808caa331119da14269ac3271c251dec3a11df896131ba2c000000000000000000000000000000000000000000000000000000000000013c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b0000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f0000000024431ecc52557993d7dbc26bc50a81d3e1f65d0de62f434a390faeefca99497f28f03d33c64c1433a818180461a535dcc7206c8b07982cd13f1af7fa229f9f5a0834251ce8bc0db519e416c0a8868385c8761f7ca5a6ad00cb254db5b68c36630b264fb6b25be47ab08630d45172a9b9c20b526ed449e50267897acb9bd133c90000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002984d86a49ea3553c56bad2dbb7151399a5ef4281892e2b881ea7701ee178c43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f3714e42ab151d853ce688205234d6f7531a931255da3c015d0066839bd8baf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100980df506642279a35f8211f10abbb31491b7dcdcc194aa9da7f7d48470326900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000800000000000000080000000000000008000000000000000800000000000000080000000000000008000000000000000800000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be2000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022a0c845d11f6ab935270159fcf81cf8fc6c19ba959855941ea0a910dfccb0aa000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026fd8601b83cf50cefc8fd01a8f4f257818b236b4b05a4d655d1e250617cca4700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000239e2829a14b926fda5538c945938ffb2d69bca6532cf8d9ef8cb03654928c21000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011ad338c82a5771b8c493d4fdd310e05a947584891295750cc1267bc96bbd0cde0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c86d02eb4dc898abeefc07e126614d7342bc55f1bb250a211861dfe87f8e30000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b0000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e10000000000000000000000000000000000000000000000000000000000000000013b9aca0005f5e100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000002013d0ff20211fe37493ef7ae818718fe839086139dccdf57e3d07f2d179e0802ad66b73a8b9536005aacaca6c565759426bcacd052db1d07f4fa5912f5731b52c52764f15c29eb4d74bd670e65ac533b62d805ac395adba6d7e074e991116a522a0c845d11f6ab935270159fcf81cf8fc6c19ba959855941ea0a910dfccb0aa0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026fd8601b83cf50cefc8fd01a8f4f257818b236b4b05a4d655d1e250617cca4700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000239e2829a14b926fda5538c945938ffb2d69bca6532cf8d9ef8cb03654928c21000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011ad338c82a5771b8c493d4fdd310e05a947584891295750cc1267bc96bbd0cde00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000080000000000000008000000000000000800000000000000080000000000000008000000000000000800000000000000080000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c86d02eb4dc898abeefc07e126614d7342bc55f1bb250a211861dfe87f8e30000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000020000000300000004000000050000000600000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000200000003000000040000000500000006000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits-types/src/index.test.ts b/yarn-project/noir-protocol-circuits-types/src/index.test.ts deleted file mode 100644 index 6f7b32e0c13a..000000000000 --- a/yarn-project/noir-protocol-circuits-types/src/index.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PrivateKernelInnerCircuitPrivateInputs, PrivateKernelTailCircuitPrivateInputs } from '@aztec/circuits.js'; -import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; -import { setupCustomSnapshotSerializers } from '@aztec/foundation/testing'; -import { fileURLToPath } from '@aztec/foundation/url'; - -import { readFileSync } from 'fs'; -import { dirname, resolve } from 'path'; - -import { executeInner, executeTail } from './index.js'; - -describe('Private kernel', () => { - let logger: DebugLogger; - - beforeAll(() => { - setupCustomSnapshotSerializers(expect); - logger = createDebugLogger('noir-private-kernel'); - }); - - // Taken from e2e_nested_contract => performs nested calls => last inner - // To regenerate fixture data run the following on the yarn-project/e2e folder - // AZTEC_GENERATE_TEST_DATA=1 yarn test e2e_nested_contract -t 'performs nested calls' - it('Executes private kernel inner for a nested call', async () => { - logger.info('Initialized Noir instance with private kernel init circuit'); - - const filepath = resolve( - dirname(fileURLToPath(import.meta.url)), - './fixtures/nested-call-private-kernel-inner.hex', - ); - const serialized = Buffer.from(readFileSync(filepath).toString(), 'hex'); - const kernelInputs = PrivateKernelInnerCircuitPrivateInputs.fromBuffer(serialized); - - const kernelOutputs = await executeInner(kernelInputs); - - expect(kernelOutputs).toMatchSnapshot(); - }); - - // Taken from e2e_nested_contract => performs nested calls => first ordering - // To regenerate fixture data run the following on the yarn-project/e2e folder - // AZTEC_GENERATE_TEST_DATA=1 yarn test e2e_nested_contract -t 'performs nested calls' - it('Executes private kernel ordering after a deployment', async () => { - const filepath = resolve( - dirname(fileURLToPath(import.meta.url)), - './fixtures/nested-call-private-kernel-ordering.hex', - ); - const serialized = Buffer.from(readFileSync(filepath).toString(), 'hex'); - const kernelInputs = PrivateKernelTailCircuitPrivateInputs.fromBuffer(serialized); - - const kernelOutputs = await executeTail(kernelInputs); - - expect(kernelOutputs).toMatchSnapshot(); - }); -}); diff --git a/yarn-project/noir-protocol-circuits-types/src/index.ts b/yarn-project/noir-protocol-circuits-types/src/index.ts index 568a5071356f..cc31ec2dde71 100644 --- a/yarn-project/noir-protocol-circuits-types/src/index.ts +++ b/yarn-project/noir-protocol-circuits-types/src/index.ts @@ -629,7 +629,7 @@ async function executePrivateKernelTailToPublicWithACVM( return decodedInputs.return_value as PublicPublicPreviousReturnType; } -const foreignCallHandler = (name: string, args: ForeignCallInput[]) => { +export const foreignCallHandler = (name: string, args: ForeignCallInput[]) => { const log = createDebugLogger('aztec:noir-protocol-circuits:oracle'); if (name === 'debugLog') { diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 67ed202f4364..d69b24594e0d 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -21,9 +21,9 @@ import { Fr, FunctionData, FunctionSelector, + Gas, GasFees, GasSettings, - GasUsed, GlobalVariables, type GrumpkinPrivateKey, GrumpkinScalar, @@ -31,6 +31,8 @@ import { KernelCircuitPublicInputs, type KernelData, type L2ToL1Message, + type LeafDataReadHint, + MAX_ENCRYPTED_LOGS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, @@ -42,6 +44,7 @@ import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX, MaxBlockNumber, type MembershipWitness, type MergeRollupInputs, @@ -76,7 +79,9 @@ import { type PublicCallData, type PublicCallStackItem, type PublicCircuitPublicInputs, + type PublicDataHint, PublicDataRead, + type PublicDataReadRequestHints, type PublicDataTreeLeaf, type PublicDataTreeLeafPreimage, PublicDataUpdateRequest, @@ -117,8 +122,8 @@ import { type FunctionLeafMembershipWitness as FunctionLeafMembershipWitnessNoir, type FunctionSelector as FunctionSelectorNoir, type GasFees as GasFeesNoir, + type Gas as GasNoir, type GasSettings as GasSettingsNoir, - type GasUsed as GasUsedNoir, type GrumpkinPrivateKey as GrumpkinPrivateKeyNoir, type L2ToL1Message as L2ToL1MessageNoir, type MaxBlockNumber as MaxBlockNumberNoir, @@ -170,8 +175,11 @@ import { type StorageUpdateRequest as StorageUpdateRequestNoir, } from './types/public_kernel_setup_types.js'; import { + type LeafDataReadHint as LeafDataReadHintNoir, type NullifierNonExistentReadRequestHints as NullifierNonExistentReadRequestHintsNoir, type NullifierNonMembershipHint as NullifierNonMembershipHintNoir, + type PublicDataHint as PublicDataHintNoir, + type PublicDataReadRequestHints as PublicDataReadRequestHintsNoir, type PublicDataUpdateRequest as PublicDataUpdateRequestNoir, type PublicKernelTailCircuitPrivateInputs as PublicKernelTailCircuitPrivateInputsNoir, } from './types/public_kernel_tail_types.js'; @@ -410,6 +418,7 @@ export function mapTxRequestToNoir(txRequest: TxRequest): TxRequestNoir { args_hash: mapFieldToNoir(txRequest.argsHash), tx_context: mapTxContextToNoir(txRequest.txContext), function_data: mapFunctionDataToNoir(txRequest.functionData), + gas_settings: mapGasSettingsToNoir(txRequest.gasSettings), }; } @@ -424,6 +433,7 @@ export function mapCallContextFromNoir(callContext: CallContextNoir): CallContex mapAztecAddressFromNoir(callContext.storage_contract_address), mapEthAddressFromNoir(callContext.portal_contract_address), mapFunctionSelectorFromNoir(callContext.function_selector), + mapGasFromNoir(callContext.gas_left), callContext.is_delegate_call, callContext.is_static_call, mapNumberFromNoir(callContext.side_effect_counter), @@ -443,6 +453,7 @@ export function mapCallContextToNoir(callContext: CallContext): CallContextNoir storage_contract_address: mapAztecAddressToNoir(callContext.storageContractAddress), portal_contract_address: mapEthAddressToNoir(callContext.portalContractAddress), function_selector: mapFunctionSelectorToNoir(callContext.functionSelector), + gas_left: mapGasToNoir(callContext.gasLeft), is_delegate_call: callContext.isDelegateCall, is_static_call: callContext.isStaticCall, side_effect_counter: mapNumberToNoir(callContext.sideEffectCounter), @@ -733,8 +744,8 @@ export function mapPrivateCircuitPublicInputsToNoir( new_l2_to_l1_msgs: mapTuple(privateCircuitPublicInputs.newL2ToL1Msgs, mapL2ToL1MessageToNoir), start_side_effect_counter: mapFieldToNoir(privateCircuitPublicInputs.startSideEffectCounter), end_side_effect_counter: mapFieldToNoir(privateCircuitPublicInputs.endSideEffectCounter), - encrypted_logs_hash: mapFieldToNoir(privateCircuitPublicInputs.encryptedLogsHash), - unencrypted_logs_hash: mapFieldToNoir(privateCircuitPublicInputs.unencryptedLogsHash), + encrypted_logs_hashes: mapTuple(privateCircuitPublicInputs.encryptedLogsHashes, mapSideEffectToNoir), + unencrypted_logs_hashes: mapTuple(privateCircuitPublicInputs.unencryptedLogsHashes, mapSideEffectToNoir), encrypted_log_preimages_length: mapFieldToNoir(privateCircuitPublicInputs.encryptedLogPreimagesLength), unencrypted_log_preimages_length: mapFieldToNoir(privateCircuitPublicInputs.unencryptedLogPreimagesLength), historical_header: mapHeaderToNoir(privateCircuitPublicInputs.historicalHeader), @@ -923,6 +934,13 @@ function mapPendingReadHintToNoir(hint: PendingReadHint): PendingReadHintNoir { }; } +function mapLeafDataReadHintToNoir(hint: LeafDataReadHint): LeafDataReadHintNoir { + return { + read_request_index: mapNumberToNoir(hint.readRequestIndex), + data_hint_index: mapNumberToNoir(hint.dataHintIndex), + }; +} + function mapNullifierSettledReadHintToNoir( hint: SettledReadHint, ): NullifierSettledReadHintNoir { @@ -961,6 +979,24 @@ function mapNullifierNonExistentReadRequestHintsToNoir( }; } +function mapPublicDataHintToNoir(hint: PublicDataHint): PublicDataHintNoir { + return { + leaf_slot: mapFieldToNoir(hint.leafSlot), + value: mapFieldToNoir(hint.value), + override_counter: mapNumberToNoir(hint.overrideCounter), + membership_witness: mapPublicDataMembershipWitnessToNoir(hint.membershipWitness), + leaf_preimage: mapPublicDataTreePreimageToNoir(hint.leafPreimage), + }; +} + +function mapPublicDataReadRequestHintsToNoir(hints: PublicDataReadRequestHints): PublicDataReadRequestHintsNoir { + return { + read_request_statuses: mapTuple(hints.readRequestStatuses, mapReadRequestStatusToNoir), + pending_read_hints: mapTuple(hints.pendingReadHints, mapPendingReadHintToNoir), + leaf_data_read_hints: mapTuple(hints.leafDataReadHints, mapLeafDataReadHintToNoir), + }; +} + function mapValidationRequestsToNoir(requests: ValidationRequests): ValidationRequestsNoir { return { for_rollup: mapRollupValidationRequestsToNoir(requests.forRollup), @@ -1008,8 +1044,12 @@ export function mapPrivateAccumulatedDataFromNoir( mapTupleFromNoir(privateAccumulatedData.new_note_hashes, MAX_NEW_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(privateAccumulatedData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), mapTupleFromNoir(privateAccumulatedData.new_l2_to_l1_msgs, MAX_NEW_L2_TO_L1_MSGS_PER_TX, mapFieldFromNoir), - mapFieldFromNoir(privateAccumulatedData.encrypted_logs_hash), - mapFieldFromNoir(privateAccumulatedData.unencrypted_logs_hash), + mapTupleFromNoir(privateAccumulatedData.encrypted_logs_hashes, MAX_ENCRYPTED_LOGS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir( + privateAccumulatedData.unencrypted_logs_hashes, + MAX_UNENCRYPTED_LOGS_PER_TX, + mapSideEffectFromNoir, + ), mapFieldFromNoir(privateAccumulatedData.encrypted_log_preimages_length), mapFieldFromNoir(privateAccumulatedData.unencrypted_log_preimages_length), mapTupleFromNoir( @@ -1022,7 +1062,7 @@ export function mapPrivateAccumulatedDataFromNoir( MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, mapCallRequestFromNoir, ), - mapGasUsedFromNoir(privateAccumulatedData.gas_used), + mapGasFromNoir(privateAccumulatedData.gas_used), ); } @@ -1031,13 +1071,13 @@ export function mapPrivateAccumulatedDataToNoir(data: PrivateAccumulatedData): P new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), new_l2_to_l1_msgs: mapTuple(data.newL2ToL1Msgs, mapFieldToNoir), - encrypted_logs_hash: mapFieldToNoir(data.encryptedLogsHash), - unencrypted_logs_hash: mapFieldToNoir(data.unencryptedLogsHash), + encrypted_logs_hashes: mapTuple(data.encryptedLogsHashes, mapSideEffectToNoir), + unencrypted_logs_hashes: mapTuple(data.unencryptedLogsHashes, mapSideEffectToNoir), encrypted_log_preimages_length: mapFieldToNoir(data.encryptedLogPreimagesLength), unencrypted_log_preimages_length: mapFieldToNoir(data.unencryptedLogPreimagesLength), private_call_stack: mapTuple(data.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), - gas_used: mapGasUsedToNoir(data.gasUsed), + gas_used: mapGasToNoir(data.gasUsed), }; } @@ -1048,8 +1088,8 @@ export function mapPublicAccumulatedDataFromNoir( mapTupleFromNoir(publicAccumulatedData.new_note_hashes, MAX_NEW_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(publicAccumulatedData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), mapTupleFromNoir(publicAccumulatedData.new_l2_to_l1_msgs, MAX_NEW_L2_TO_L1_MSGS_PER_TX, mapFieldFromNoir), - mapFieldFromNoir(publicAccumulatedData.encrypted_logs_hash), - mapFieldFromNoir(publicAccumulatedData.unencrypted_logs_hash), + mapTupleFromNoir(publicAccumulatedData.encrypted_logs_hashes, MAX_ENCRYPTED_LOGS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(publicAccumulatedData.unencrypted_logs_hashes, MAX_UNENCRYPTED_LOGS_PER_TX, mapSideEffectFromNoir), mapFieldFromNoir(publicAccumulatedData.encrypted_log_preimages_length), mapFieldFromNoir(publicAccumulatedData.unencrypted_log_preimages_length), mapTupleFromNoir( @@ -1062,7 +1102,7 @@ export function mapPublicAccumulatedDataFromNoir( MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, mapCallRequestFromNoir, ), - mapGasUsedFromNoir(publicAccumulatedData.gas_used), + mapGasFromNoir(publicAccumulatedData.gas_used), ); } @@ -1073,8 +1113,8 @@ export function mapPublicAccumulatedDataToNoir( new_note_hashes: mapTuple(publicAccumulatedData.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(publicAccumulatedData.newNullifiers, mapSideEffectLinkedToNoir), new_l2_to_l1_msgs: mapTuple(publicAccumulatedData.newL2ToL1Msgs, mapFieldToNoir), - encrypted_logs_hash: mapFieldToNoir(publicAccumulatedData.encryptedLogsHash), - unencrypted_logs_hash: mapFieldToNoir(publicAccumulatedData.unencryptedLogsHash), + encrypted_logs_hashes: mapTuple(publicAccumulatedData.encryptedLogsHashes, mapSideEffectToNoir), + unencrypted_logs_hashes: mapTuple(publicAccumulatedData.unencryptedLogsHashes, mapSideEffectToNoir), encrypted_log_preimages_length: mapFieldToNoir(publicAccumulatedData.encryptedLogPreimagesLength), unencrypted_log_preimages_length: mapFieldToNoir(publicAccumulatedData.unencryptedLogPreimagesLength), public_data_update_requests: mapTuple( @@ -1082,19 +1122,19 @@ export function mapPublicAccumulatedDataToNoir( mapPublicDataUpdateRequestToNoir, ), public_call_stack: mapTuple(publicAccumulatedData.publicCallStack, mapCallRequestToNoir), - gas_used: mapGasUsedToNoir(publicAccumulatedData.gasUsed), + gas_used: mapGasToNoir(publicAccumulatedData.gasUsed), }; } -export function mapGasUsedFromNoir(gasUsed: GasUsedNoir): GasUsed { - return GasUsed.from({ +export function mapGasFromNoir(gasUsed: GasNoir): Gas { + return Gas.from({ daGas: mapNumberFromNoir(gasUsed.da_gas), l1Gas: mapNumberFromNoir(gasUsed.l1_gas), l2Gas: mapNumberFromNoir(gasUsed.l2_gas), }); } -export function mapGasUsedToNoir(gasUsed: GasUsed): GasUsedNoir { +export function mapGasToNoir(gasUsed: Gas): GasNoir { return { da_gas: mapNumberToNoir(gasUsed.daGas), l1_gas: mapNumberToNoir(gasUsed.l1Gas), @@ -1150,7 +1190,7 @@ export function mapCombinedAccumulatedDataFromNoir( MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, mapPublicDataUpdateRequestFromNoir, ), - mapGasUsedFromNoir(combinedAccumulatedData.gas_used), + mapGasFromNoir(combinedAccumulatedData.gas_used), ); } @@ -1169,7 +1209,7 @@ export function mapCombinedAccumulatedDataToNoir( combinedAccumulatedData.publicDataUpdateRequests, mapPublicDataUpdateRequestToNoir, ), - gas_used: mapGasUsedToNoir(combinedAccumulatedData.gasUsed), + gas_used: mapGasToNoir(combinedAccumulatedData.gasUsed), }; } @@ -1218,6 +1258,7 @@ export function mapKernelCircuitPublicInputsFromNoir(inputs: KernelCircuitPublic mapRollupValidationRequestsFromNoir(inputs.rollup_validation_requests), mapCombinedAccumulatedDataFromNoir(inputs.end), mapCombinedConstantDataFromNoir(inputs.constants), + mapPartialStateReferenceFromNoir(inputs.start_state), mapRevertCodeFromNoir(inputs.revert_code), ); } @@ -1228,6 +1269,7 @@ export function mapKernelCircuitPublicInputsToNoir(inputs: KernelCircuitPublicIn rollup_validation_requests: mapRollupValidationRequestsToNoir(inputs.rollupValidationRequests), constants: mapCombinedConstantDataToNoir(inputs.constants), end: mapCombinedAccumulatedDataToNoir(inputs.end), + start_state: mapPartialStateReferenceToNoir(inputs.startState), revert_code: mapRevertCodeToNoir(inputs.revertCode), }; } @@ -1358,6 +1400,10 @@ export function mapPrivateKernelTailCircuitPrivateInputsToNoir( sorted_new_nullifiers_indexes: mapTuple(inputs.sortedNewNullifiersIndexes, mapNumberToNoir), nullifier_read_request_hints: mapNullifierReadRequestHintsToNoir(inputs.nullifierReadRequestHints), nullifier_commitment_hints: mapTuple(inputs.nullifierCommitmentHints, mapFieldToNoir), + sorted_encrypted_log_hashes: mapTuple(inputs.sortedEncryptedLogHashes, mapSideEffectToNoir), + sorted_encrypted_log_hashes_indexes: mapTuple(inputs.sortedEncryptedLogHashesIndexes, mapNumberToNoir), + sorted_unencrypted_log_hashes: mapTuple(inputs.sortedUnencryptedLogHashes, mapSideEffectToNoir), + sorted_unencrypted_log_hashes_indexes: mapTuple(inputs.sortedUnencryptedLogHashesIndexes, mapNumberToNoir), master_nullifier_secret_keys: mapTuple(inputs.masterNullifierSecretKeys, mapGrumpkinPrivateKeyToNoir), }; } @@ -1374,6 +1420,10 @@ export function mapPrivateKernelTailToPublicCircuitPrivateInputsToNoir( sorted_new_nullifiers_indexes: mapTuple(inputs.sortedNewNullifiersIndexes, mapNumberToNoir), nullifier_read_request_hints: mapNullifierReadRequestHintsToNoir(inputs.nullifierReadRequestHints), nullifier_commitment_hints: mapTuple(inputs.nullifierCommitmentHints, mapFieldToNoir), + sorted_encrypted_log_hashes: mapTuple(inputs.sortedEncryptedLogHashes, mapSideEffectToNoir), + sorted_encrypted_log_hashes_indexes: mapTuple(inputs.sortedEncryptedLogHashesIndexes, mapNumberToNoir), + sorted_unencrypted_log_hashes: mapTuple(inputs.sortedUnencryptedLogHashes, mapSideEffectToNoir), + sorted_unencrypted_log_hashes_indexes: mapTuple(inputs.sortedUnencryptedLogHashesIndexes, mapNumberToNoir), master_nullifier_secret_keys: mapTuple(inputs.masterNullifierSecretKeys, mapGrumpkinPrivateKeyToNoir), }; } @@ -1396,6 +1446,9 @@ export function mapPublicKernelTailCircuitPrivateInputsToNoir( nullifier_non_existent_read_request_hints: mapNullifierNonExistentReadRequestHintsToNoir( inputs.nullifierNonExistentReadRequestHints, ), + public_data_hints: mapTuple(inputs.publicDataHints, mapPublicDataHintToNoir), + public_data_read_request_hints: mapPublicDataReadRequestHintsToNoir(inputs.publicDataReadRequestHints), + start_state: mapPartialStateReferenceToNoir(inputs.startState), }; } @@ -1527,12 +1580,12 @@ export function mapPublicCircuitPublicInputsToNoir( new_l2_to_l1_msgs: mapTuple(publicInputs.newL2ToL1Msgs, mapL2ToL1MessageToNoir), start_side_effect_counter: mapFieldToNoir(publicInputs.startSideEffectCounter), end_side_effect_counter: mapFieldToNoir(publicInputs.endSideEffectCounter), - unencrypted_logs_hash: mapFieldToNoir(publicInputs.unencryptedLogsHash), + unencrypted_logs_hashes: mapTuple(publicInputs.unencryptedLogsHashes, mapSideEffectToNoir), unencrypted_log_preimages_length: mapFieldToNoir(publicInputs.unencryptedLogPreimagesLength), historical_header: mapHeaderToNoir(publicInputs.historicalHeader), - prover_address: mapAztecAddressToNoir(publicInputs.proverAddress), revert_code: mapRevertCodeToNoir(publicInputs.revertCode), + gas_left: mapGasToNoir(publicInputs.gasLeft), }; } /** diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator.ts b/yarn-project/prover-client/src/orchestrator/orchestrator.ts index 4bf498b96ebb..88ae37c05d07 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator.ts @@ -415,6 +415,28 @@ export class ProvingOrchestrator { // Executes the base rollup circuit and stored the output as intermediate state for the parent merge/root circuit // Executes the next level of merge if all inputs are available private async runBaseRollup(provingState: ProvingState | undefined, index: bigint, tx: TxProvingState) { + if ( + !tx.baseRollupInputs.kernelData.publicInputs.end.encryptedLogsHash + .toBuffer() + .equals(tx.processedTx.encryptedLogs.hash()) + ) { + throw new Error( + `Encrypted logs hash mismatch: ${ + tx.baseRollupInputs.kernelData.publicInputs.end.encryptedLogsHash + } === ${Fr.fromBuffer(tx.processedTx.encryptedLogs.hash())}`, + ); + } + if ( + !tx.baseRollupInputs.kernelData.publicInputs.end.unencryptedLogsHash + .toBuffer() + .equals(tx.processedTx.unencryptedLogs.hash()) + ) { + throw new Error( + `Unencrypted logs hash mismatch: ${ + tx.baseRollupInputs.kernelData.publicInputs.end.unencryptedLogsHash + } === ${Fr.fromBuffer(tx.processedTx.unencryptedLogs.hash())}`, + ); + } if (!provingState?.verifyState()) { logger.debug('Not running base rollup, state invalid'); return; diff --git a/yarn-project/pxe/src/kernel_prover/hints_builder.ts b/yarn-project/pxe/src/kernel_prover/hints_builder.ts index f57f1d8c7b4a..dea4ae58b962 100644 --- a/yarn-project/pxe/src/kernel_prover/hints_builder.ts +++ b/yarn-project/pxe/src/kernel_prover/hints_builder.ts @@ -84,7 +84,7 @@ export class HintsBuilder { async getNullifierMembershipWitness(nullifier: Fr) { const res = await this.oracle.getNullifierMembershipWitness(nullifier); if (!res) { - return; + throw new Error(`Cannot find the leaf for nullifier ${nullifier.toBigInt()}.`); } const { index, siblingPath, leafPreimage } = res; diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 0e0687f9bb7a..1632ebc31643 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -1,11 +1,13 @@ import { CallRequest, Fr, + type MAX_ENCRYPTED_LOGS_PER_TX, type MAX_NEW_NOTE_HASHES_PER_TX, type MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, + type MAX_UNENCRYPTED_LOGS_PER_TX, NoteHashReadRequestMembershipWitness, PrivateCallData, PrivateKernelCircuitPublicInputs, @@ -162,11 +164,20 @@ export class KernelProver { typeof MAX_NEW_NULLIFIERS_PER_TX >(output.publicInputs.end.newNullifiers); + const [sortedEncryptedLogHashes, sortedEncryptedLogHashesIndexes] = this.hintsBuilder.sortSideEffects< + SideEffect, + typeof MAX_ENCRYPTED_LOGS_PER_TX + >(output.publicInputs.end.encryptedLogsHashes); + + const [sortedUnencryptedLogHashes, sortedUnencryptedLogHashesIndexes] = this.hintsBuilder.sortSideEffects< + SideEffect, + typeof MAX_UNENCRYPTED_LOGS_PER_TX + >(output.publicInputs.end.unencryptedLogsHashes); + const nullifierNoteHashHints = this.hintsBuilder.getNullifierHints( mapTuple(sortedNullifiers, n => n.noteHash), sortedNoteHashes, ); - this.log.debug( `Calling private kernel tail with hwm ${previousKernelData.publicInputs.minRevertibleSideEffectCounter}`, ); @@ -180,6 +191,10 @@ export class KernelProver { sortedNullifiersIndexes, nullifierReadRequestHints, nullifierNoteHashHints, + sortedEncryptedLogHashes, + sortedEncryptedLogHashesIndexes, + sortedUnencryptedLogHashes, + sortedUnencryptedLogHashesIndexes, masterNullifierSecretKeys, ); pushTestData('private-kernel-inputs-ordering', privateInputs); diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 45f0a9eb16ed..9f1d341533d6 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -1,6 +1,8 @@ import { type AuthWitness, type AztecNode, + EncryptedFunctionL2Logs, + type EncryptedL2Log, EncryptedTxL2Logs, ExtendedNote, type FunctionCall, @@ -18,6 +20,8 @@ import { type TxExecutionRequest, type TxHash, type TxReceipt, + UnencryptedFunctionL2Logs, + type UnencryptedL2Log, UnencryptedTxL2Logs, isNoirCallStackUnresolved, } from '@aztec/circuit-types'; @@ -32,6 +36,7 @@ import { type PartialAddress, type PrivateKernelTailCircuitPublicInputs, type PublicCallRequest, + type SideEffect, computeContractClassId, getContractClassFromArtifact, } from '@aztec/circuits.js'; @@ -417,8 +422,7 @@ export class PXEService implements PXE { } if (simulatePublic) { - // Only one transaction, so we can take index 0. - simulatedTx.publicReturnValues = (await this.#simulatePublicCalls(simulatedTx.tx))[0]; + simulatedTx.publicReturnValues = await this.#simulatePublicCalls(simulatedTx.tx); } if (!msgSender) { @@ -637,8 +641,7 @@ export class PXEService implements PXE { this.log.debug(`Executing kernel prover...`); const { proof, publicInputs } = await kernelProver.prove(txExecutionRequest.toTxRequest(), executionResult); - const encryptedLogs = new EncryptedTxL2Logs(collectEncryptedLogs(executionResult)); - const unencryptedLogs = new UnencryptedTxL2Logs(collectUnencryptedLogs(executionResult)); + const { encryptedLogs, unencryptedLogs } = this.patchLogsOrdering(executionResult); const enqueuedPublicFunctions = collectEnqueuedPublicFunctionCalls(executionResult); // HACK(#1639): Manually patches the ordering of the public call stack @@ -646,7 +649,7 @@ export class PXEService implements PXE { await this.patchPublicCallStackOrdering(publicInputs, enqueuedPublicFunctions); const tx = new Tx(publicInputs, proof, encryptedLogs, unencryptedLogs, enqueuedPublicFunctions); - return new SimulatedTx(tx, [executionResult.returnValues]); + return new SimulatedTx(tx, executionResult.returnValues); } /** @@ -756,6 +759,61 @@ export class PXEService implements PXE { ); } + // As above, this is a hack for encrypted/unencrypted logs ordering, now they are sorted. Since the private kernel + // cannot keep track of side effects that happen after or before a nested call, we override the gathered logs. + // As a sanity check, we at least verify that the elements are the same, so we are only tweaking their ordering. + // See yarn-project/end-to-end/src/e2e_ordering.test.ts + // See https://github.com/AztecProtocol/aztec-packages/issues/1641 + // Added as part of resolving #5017 + private patchLogsOrdering(execResult: ExecutionResult) { + const encLogs = collectEncryptedLogs(execResult).flatMap(l => l.logs); + const unencLogs = collectUnencryptedLogs(execResult).flatMap(l => l.logs); + const getLogs = (res: ExecutionResult, enc: boolean) => { + const logs: SideEffect[] = enc + ? res.callStackItem.publicInputs.encryptedLogsHashes.concat(res.nestedExecutions.flatMap(e => getLogs(e, true))) + : res.callStackItem.publicInputs.unencryptedLogsHashes.concat( + res.nestedExecutions.flatMap(e => getLogs(e, false)), + ); + + return logs; + }; + + const sortSEs = (a: SideEffect, b: SideEffect) => { + if (a.isEmpty()) { + return 1; + } else if (b.isEmpty()) { + return -1; + } else { + return Number(a.counter.toBigInt() - b.counter.toBigInt()); + } + }; + + const sortedEncLogs = getLogs(execResult, true).sort(sortSEs); + const sortedUnencLogs = getLogs(execResult, false).sort(sortSEs); + + const finalEncLogs: EncryptedL2Log[] = []; + sortedEncLogs.forEach((sideEffect: SideEffect) => { + if (!sideEffect.isEmpty()) { + const isLog = (log: EncryptedL2Log) => Fr.fromBuffer(log.hash()).equals(sideEffect.value); + const thisLogIndex = encLogs.findIndex(isLog); + finalEncLogs.push(encLogs[thisLogIndex]); + } + }); + + const finalUnencLogs: UnencryptedL2Log[] = []; + sortedUnencLogs.forEach((sideEffect: SideEffect) => { + if (!sideEffect.isEmpty()) { + const isLog = (log: UnencryptedL2Log) => Fr.fromBuffer(log.hash()).equals(sideEffect.value); + const thisLogIndex = unencLogs.findIndex(isLog); + finalUnencLogs.push(unencLogs[thisLogIndex]); + } + }); + + const encryptedLogs = new EncryptedTxL2Logs([new EncryptedFunctionL2Logs(finalEncLogs)]); + const unencryptedLogs = new UnencryptedTxL2Logs([new UnencryptedFunctionL2Logs(finalUnencLogs)]); + return { encryptedLogs, unencryptedLogs }; + } + public async isGlobalStateSynchronized() { return await this.synchronizer.isGlobalStateSynchronized(); } diff --git a/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts b/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts index 314995a4fd5a..39c3e395ca48 100644 --- a/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts +++ b/yarn-project/pxe/src/pxe_service/test/pxe_test_suite.ts @@ -10,6 +10,7 @@ import { CompleteAddress, Fr, FunctionData, + GasSettings, INITIAL_L2_BLOCK_NUM, Point, TxContext, @@ -133,6 +134,7 @@ export const pxeTestSuite = (testName: string, pxeSetup: () => Promise) => txContext: TxContext.empty(), packedArguments: [], authWitnesses: [], + gasSettings: GasSettings.default(), }); await expect(async () => await pxe.proveTx(txExecutionRequest, false)).rejects.toThrow( diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 56e65ee0e816..d5ba6c1a032d 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -159,6 +159,11 @@ export class SimulatorOracle implements DBOracle { return new MessageLoadOracleInputs(messageIndex, siblingPath); } + // Only used in public. + public getL1ToL2LeafValue(_leafIndex: bigint): Promise { + throw new Error('Unimplemented in private!'); + } + /** * Gets the index of a commitment in the note hash tree. * @param commitment - The commitment. diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.test.ts b/yarn-project/pxe/src/synchronizer/synchronizer.test.ts index 81f079c6b7e8..79fa9b9bd199 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.test.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.test.ts @@ -158,15 +158,15 @@ describe('Synchronizer', () => { }); class TestSynchronizer extends Synchronizer { - public work(limit = 1) { + public override work(limit = 1) { return super.work(limit); } - public initialSync(): Promise { + public override initialSync(): Promise { return super.initialSync(); } - public workNoteProcessorCatchUp(limit = 1): Promise { + public override workNoteProcessorCatchUp(limit = 1): Promise { return super.workNoteProcessorCatchUp(limit); } } diff --git a/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts b/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts index 33766cfa2c18..3ec8a8eb64cd 100644 --- a/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts +++ b/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts @@ -90,7 +90,7 @@ export class SimpleTestGlobalVariableBuilder implements GlobalVariableBuilder { `Built global variables for block ${blockNumber}: (${chainId}, ${version}, ${blockNumber}, ${lastTimestamp}, ${coinbase}, ${feeRecipient})`, ); - const gasFees = GasFees.empty(); // TODO(palla/gas-in-circuits) + const gasFees = GasFees.default(); return new GlobalVariables(chainId, version, blockNumber, lastTimestamp, coinbase, feeRecipient, gasFees); } } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index 72af68c53fc4..38e0379fbab2 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -270,11 +270,11 @@ describe('sequencer', () => { }); class TestSubject extends Sequencer { - public work() { + public override work() { return super.work(); } - public initialSync(): Promise { + public override initialSync(): Promise { return super.initialSync(); } } diff --git a/yarn-project/simulator/src/acvm/oracle/oracle.ts b/yarn-project/simulator/src/acvm/oracle/oracle.ts index c9223ae8f1de..fb3b35f028cf 100644 --- a/yarn-project/simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/oracle.ts @@ -21,8 +21,13 @@ export class Oracle { return toACVMField(val); } - async packArguments(args: ACVMField[]): Promise { - const packed = await this.typedOracle.packArguments(args.map(fromACVMField)); + async packArgumentsArray(args: ACVMField[]): Promise { + const packed = await this.typedOracle.packArgumentsArray(args.map(fromACVMField)); + return toACVMField(packed); + } + + async packArguments(_length: ACVMField[], values: ACVMField[]): Promise { + const packed = await this.typedOracle.packArgumentsArray(values.map(fromACVMField)); return toACVMField(packed); } @@ -291,14 +296,14 @@ export class Oracle { log: ACVMField[], ): ACVMField { const publicKey = new Point(fromACVMField(publicKeyX), fromACVMField(publicKeyY)); - this.typedOracle.emitEncryptedLog( + const logHash = this.typedOracle.emitEncryptedLog( AztecAddress.fromString(contractAddress), Fr.fromString(storageSlot), Fr.fromString(noteTypeId), publicKey, log.map(fromACVMField), ); - return toACVMField(0); + return toACVMField(logHash); } emitUnencryptedLog([contractAddress]: ACVMField[], [eventSelector]: ACVMField[], message: ACVMField[]): ACVMField { @@ -309,8 +314,8 @@ export class Oracle { logPayload, ); - this.typedOracle.emitUnencryptedLog(log); - return toACVMField(0); + const logHash = this.typedOracle.emitUnencryptedLog(log); + return toACVMField(logHash); } debugLog(...args: ACVMField[][]): ACVMField { diff --git a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts index 4f245732275b..c362a04f8be0 100644 --- a/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/simulator/src/acvm/oracle/typed_oracle.ts @@ -85,8 +85,8 @@ export abstract class TypedOracle { return Fr.random(); } - packArguments(_args: Fr[]): Promise { - throw new OracleMethodNotAvailableError('packArguments'); + packArgumentsArray(_args: Fr[]): Promise { + throw new OracleMethodNotAvailableError('packArgumentsArray'); } packReturns(_returns: Fr[]): Promise { @@ -205,11 +205,11 @@ export abstract class TypedOracle { _noteTypeId: Fr, _publicKey: PublicKey, _log: Fr[], - ): void { + ): Fr { throw new OracleMethodNotAvailableError('emitEncryptedLog'); } - emitUnencryptedLog(_log: UnencryptedL2Log): void { + emitUnencryptedLog(_log: UnencryptedL2Log): Fr { throw new OracleMethodNotAvailableError('emitUnencryptedLog'); } diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.ts b/yarn-project/simulator/src/avm/avm_execution_environment.ts index c21fb948a980..def966f15ed2 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.ts @@ -1,4 +1,4 @@ -import { FunctionSelector, type GlobalVariables, type Header } from '@aztec/circuits.js'; +import { FunctionSelector, type GasSettings, type GlobalVariables, type Header } from '@aztec/circuits.js'; import { computeVarArgsHash } from '@aztec/circuits.js/hash'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { type EthAddress } from '@aztec/foundation/eth-address'; @@ -23,7 +23,6 @@ export class AvmExecutionEnvironment { constructor( public readonly address: AztecAddress, public readonly storageAddress: AztecAddress, - public readonly origin: AztecAddress, public readonly sender: AztecAddress, public readonly portal: EthAddress, public readonly feePerL1Gas: Fr, @@ -35,6 +34,8 @@ export class AvmExecutionEnvironment { public readonly isStaticCall: boolean, public readonly isDelegateCall: boolean, public readonly calldata: Fr[], + public readonly gasSettings: GasSettings, + public readonly transactionFee: Fr, // Function selector is temporary since eventually public contract bytecode will be one blob // containing all functions, and function selector will become an application-level mechanism @@ -55,7 +56,6 @@ export class AvmExecutionEnvironment { return new AvmExecutionEnvironment( targetAddress, /*storageAddress=*/ targetAddress, - this.origin, this.address, this.portal, this.feePerL1Gas, @@ -67,6 +67,8 @@ export class AvmExecutionEnvironment { this.isStaticCall, this.isDelegateCall, calldata, + this.gasSettings, + this.transactionFee, temporaryFunctionSelector, ); } @@ -79,7 +81,6 @@ export class AvmExecutionEnvironment { return new AvmExecutionEnvironment( address, /*storageAddress=*/ address, - this.origin, this.sender, this.portal, this.feePerL1Gas, @@ -91,6 +92,8 @@ export class AvmExecutionEnvironment { /*isStaticCall=*/ true, this.isDelegateCall, calldata, + this.gasSettings, + this.transactionFee, temporaryFunctionSelector, ); } @@ -103,7 +106,6 @@ export class AvmExecutionEnvironment { return new AvmExecutionEnvironment( address, this.storageAddress, - this.origin, this.sender, this.portal, this.feePerL1Gas, @@ -115,6 +117,8 @@ export class AvmExecutionEnvironment { this.isStaticCall, /*isDelegateCall=*/ true, calldata, + this.gasSettings, + this.transactionFee, temporaryFunctionSelector, ); } diff --git a/yarn-project/simulator/src/avm/avm_gas.ts b/yarn-project/simulator/src/avm/avm_gas.ts index 5a80d70baf97..77ee61739966 100644 --- a/yarn-project/simulator/src/avm/avm_gas.ts +++ b/yarn-project/simulator/src/avm/avm_gas.ts @@ -78,7 +78,6 @@ export const GasCosts: Record = { // Execution environment [Opcode.ADDRESS]: TemporaryDefaultGasCost, [Opcode.STORAGEADDRESS]: TemporaryDefaultGasCost, - [Opcode.ORIGIN]: TemporaryDefaultGasCost, [Opcode.SENDER]: TemporaryDefaultGasCost, [Opcode.PORTAL]: TemporaryDefaultGasCost, [Opcode.FEEPERL1GAS]: TemporaryDefaultGasCost, diff --git a/yarn-project/simulator/src/avm/avm_machine_state.ts b/yarn-project/simulator/src/avm/avm_machine_state.ts index 178ca1adcf25..8ebfa6b1e47d 100644 --- a/yarn-project/simulator/src/avm/avm_machine_state.ts +++ b/yarn-project/simulator/src/avm/avm_machine_state.ts @@ -44,10 +44,20 @@ export class AvmMachineState { /** Output data must NOT be modified once it is set */ private output: Fr[] = []; - constructor(l1GasLeft: number, l2GasLeft: number, daGasLeft: number) { - this.l1GasLeft = l1GasLeft; - this.l2GasLeft = l2GasLeft; - this.daGasLeft = daGasLeft; + constructor(gasLeft: Gas); + constructor(l1GasLeft: number, l2GasLeft: number, daGasLeft: number); + constructor(gasLeftOrL1GasLeft: Gas | number, l2GasLeft?: number, daGasLeft?: number) { + if (typeof gasLeftOrL1GasLeft === 'object') { + ({ l1Gas: this.l1GasLeft, l2Gas: this.l2GasLeft, daGas: this.daGasLeft } = gasLeftOrL1GasLeft); + } else { + this.l1GasLeft = gasLeftOrL1GasLeft; + this.l2GasLeft = l2GasLeft!; + this.daGasLeft = daGasLeft!; + } + } + + public get gasLeft(): Gas { + return { l1Gas: this.l1GasLeft, l2Gas: this.l2GasLeft, daGas: this.daGasLeft }; } public static fromState(state: InitialAvmMachineState): AvmMachineState { @@ -128,6 +138,17 @@ export class AvmMachineState { if (!this.halted) { throw new Error('Execution results are not ready! Execution is ongoing.'); } - return new AvmContractCallResults(this.reverted, this.output); + let revertReason = undefined; + if (this.reverted && this.output.length > 0) { + try { + // Try to interpret the output as a text string. + revertReason = new Error( + 'Reverted with output: ' + String.fromCharCode(...this.output.map(fr => fr.toNumber())), + ); + } catch (e) { + revertReason = new Error('Reverted with non-string output'); + } + } + return new AvmContractCallResults(this.reverted, this.output, revertReason); } } diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index d6026089f1c3..411d6c8fa84b 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -20,7 +20,6 @@ import { initContext, initExecutionEnvironment, initGlobalVariables, - initL1ToL2MessageOracleInput, initMachineState, randomMemoryBytes, randomMemoryFields, @@ -106,6 +105,18 @@ describe('AVM simulator: transpiled Noir contracts', () => { expect(results.output).toEqual([new Fr(4), new Fr(6)]); }); + it('Assertion message', async () => { + const calldata: Fr[] = [new Fr(20)]; + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + + const bytecode = getAvmTestContractBytecode('assert_nullifier_exists'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(true); + expect(results.revertReason?.message).toEqual("Reverted with output: Nullifier doesn't exist!"); + expect(results.output).toEqual([..."Nullifier doesn't exist!"].flatMap(c => new Fr(c.charCodeAt(0)))); + }); + describe.each([ ['set_opcode_u8', 8n], ['set_opcode_u32', 1n << 30n], @@ -124,23 +135,11 @@ describe('AVM simulator: transpiled Noir contracts', () => { }); describe.each([ - [ - 'sha256_hash', - /*input=*/ randomMemoryBytes(10), - /*output=*/ (bytes: Uint8[]) => [...sha256(Buffer.concat(bytes.map(b => b.toBuffer())))].map(b => new Fr(b)), - ], - [ - 'keccak_hash', - /*input=*/ randomMemoryBytes(10), - /*output=*/ (bytes: Uint8[]) => [...keccak256(Buffer.concat(bytes.map(b => b.toBuffer())))].map(b => new Fr(b)), - ], - ['poseidon2_hash', /*input=*/ randomMemoryFields(10), /*output=*/ (fields: Fieldable[]) => [poseidon2Hash(fields)]], - ['pedersen_hash', /*input=*/ randomMemoryFields(10), /*output=*/ (fields: Fieldable[]) => [pedersenHash(fields)]], - [ - 'pedersen_hash_with_index', - /*input=*/ randomMemoryFields(10), - /*output=*/ (fields: Fieldable[]) => [pedersenHash(fields, /*index=*/ 20)], - ], + ['sha256_hash', /*input=*/ randomMemoryBytes(10), /*output=*/ sha256FromMemoryBytes], + ['keccak_hash', /*input=*/ randomMemoryBytes(10), /*output=*/ keccak256FromMemoryBytes], + ['poseidon2_hash', /*input=*/ randomMemoryFields(10), /*output=*/ poseidon2FromMemoryFields], + ['pedersen_hash', /*input=*/ randomMemoryFields(10), /*output=*/ pedersenFromMemoryFields], + ['pedersen_hash_with_index', /*input=*/ randomMemoryFields(10), /*output=*/ indexedPedersenFromMemoryFields], ])('Hashes in noir contracts', (name: string, input: MemoryValue[], output: (msg: any[]) => Fr[]) => { it(`Should execute contract function that performs ${name}`, async () => { const calldata = input.map(e => e.toFr()); @@ -189,11 +188,6 @@ describe('AVM simulator: transpiled Noir contracts', () => { await testEnvGetter('sender', sender, 'get_sender'); }); - it('origin', async () => { - const origin = AztecAddress.fromField(new Fr(1)); - await testEnvGetter('origin', origin, 'get_origin'); - }); - it('portal', async () => { const portal = EthAddress.fromField(new Fr(1)); await testEnvGetter('portal', portal, 'get_portal'); @@ -454,6 +448,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const results = await new AvmSimulator(context).executeBytecode(bytecode); expect(results.reverted).toBe(true); + expect(results.revertReason?.message).toMatch(/Attempted to emit duplicate nullifier/); // Only the first nullifier should be in the trace, second one failed to add expect(context.persistableState.flush().newNullifiers).toEqual([ expect.objectContaining({ @@ -488,9 +483,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const calldata = [msgHash, leafIndex]; const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - jest - .spyOn(context.persistableState.hostStorage.commitmentsDb, 'getL1ToL2MembershipWitness') - .mockResolvedValue(initL1ToL2MessageOracleInput(leafIndex.toBigInt())); + jest.spyOn(context.persistableState.hostStorage.commitmentsDb, 'getL1ToL2LeafValue').mockResolvedValue(msgHash); const bytecode = getAvmTestContractBytecode('l1_to_l2_msg_exists'); const results = await new AvmSimulator(context).executeBytecode(bytecode); @@ -899,8 +892,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const results = await new AvmSimulator(context).executeBytecode(callBytecode); expect(results.reverted).toBe(true); // The outer call should revert. - // TODO(fcarreiro): revertReason lost in translation between results. - // expect(results.revertReason).toEqual(/StaticCallStorageAlterError/); + expect(results.revertReason?.message).toMatch(/Nested static call failed/); }); }); }); @@ -922,3 +914,23 @@ function getAvmNestedCallsTestContractBytecode(functionName: string): Buffer { ); return artifact.bytecode; } + +function sha256FromMemoryBytes(bytes: Uint8[]): Fr[] { + return [...sha256(Buffer.concat(bytes.map(b => b.toBuffer())))].map(b => new Fr(b)); +} + +function keccak256FromMemoryBytes(bytes: Uint8[]): Fr[] { + return [...keccak256(Buffer.concat(bytes.map(b => b.toBuffer())))].map(b => new Fr(b)); +} + +function poseidon2FromMemoryFields(fields: Fieldable[]): Fr[] { + return [poseidon2Hash(fields)]; +} + +function pedersenFromMemoryFields(fields: Fieldable[]): Fr[] { + return [pedersenHash(fields)]; +} + +function indexedPedersenFromMemoryFields(fields: Fieldable[]): Fr[] { + return [pedersenHash(fields, /*index=*/ 20)]; +} diff --git a/yarn-project/simulator/src/avm/fixtures/index.ts b/yarn-project/simulator/src/avm/fixtures/index.ts index f73e82f2facc..ef9233bb686f 100644 --- a/yarn-project/simulator/src/avm/fixtures/index.ts +++ b/yarn-project/simulator/src/avm/fixtures/index.ts @@ -1,5 +1,4 @@ -import { SiblingPath } from '@aztec/circuit-types'; -import { GasFees, GlobalVariables, Header, L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/circuits.js'; +import { GasFees, GasSettings, GlobalVariables, Header } from '@aztec/circuits.js'; import { FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -8,12 +7,7 @@ import { Fr } from '@aztec/foundation/fields'; import { mock } from 'jest-mock-extended'; import merge from 'lodash.merge'; -import { - type CommitmentsDB, - MessageLoadOracleInputs, - type PublicContractsDB, - type PublicStateDB, -} from '../../index.js'; +import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from '../../index.js'; import { AvmContext } from '../avm_context.js'; import { AvmContextInputs, AvmExecutionEnvironment } from '../avm_execution_environment.js'; import { AvmMachineState } from '../avm_machine_state.js'; @@ -61,7 +55,6 @@ export function initExecutionEnvironment(overrides?: Partial { - return new MessageLoadOracleInputs( - leafIndex ?? 0n, - new SiblingPath(L1_TO_L2_MSG_TREE_HEIGHT, Array(L1_TO_L2_MSG_TREE_HEIGHT)), - ); -} - /** * Adjust the user index to account for the AvmContextInputs size. * This is a hack for testing, and should go away once AvmContextInputs themselves go away. diff --git a/yarn-project/simulator/src/avm/journal/journal.test.ts b/yarn-project/simulator/src/avm/journal/journal.test.ts index 400d70669215..8a42f1e6796e 100644 --- a/yarn-project/simulator/src/avm/journal/journal.test.ts +++ b/yarn-project/simulator/src/avm/journal/journal.test.ts @@ -6,7 +6,6 @@ import { Fr } from '@aztec/foundation/fields'; import { type MockProxy, mock } from 'jest-mock-extended'; import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from '../../index.js'; -import { initL1ToL2MessageOracleInput } from '../fixtures/index.js'; import { HostStorage } from './host_storage.js'; import { AvmPersistableStateManager, type JournalData } from './journal.js'; @@ -114,28 +113,28 @@ describe('journal', () => { ]); }); it('checkL1ToL2MessageExists works for missing message', async () => { - const utxo = new Fr(2); + const msgHash = new Fr(2); const leafIndex = new Fr(42); - const exists = await journal.checkL1ToL2MessageExists(utxo, leafIndex); + const exists = await journal.checkL1ToL2MessageExists(msgHash, leafIndex); expect(exists).toEqual(false); const journalUpdates = journal.flush(); expect(journalUpdates.l1ToL2MessageChecks).toEqual([ - expect.objectContaining({ leafIndex: leafIndex, msgHash: utxo, exists: false }), + expect.objectContaining({ leafIndex: leafIndex, msgHash, exists: false }), ]); }); - it('checkL1ToL2MessageExists works for existing nullifiers', async () => { - const utxo = new Fr(2); + it('checkL1ToL2MessageExists works for existing msgHash', async () => { + const msgHash = new Fr(2); const leafIndex = new Fr(42); - commitmentsDb.getL1ToL2MembershipWitness.mockResolvedValue(initL1ToL2MessageOracleInput(leafIndex.toBigInt())); - const exists = await journal.checkL1ToL2MessageExists(utxo, leafIndex); + commitmentsDb.getL1ToL2LeafValue.mockResolvedValue(msgHash); + const exists = await journal.checkL1ToL2MessageExists(msgHash, leafIndex); expect(exists).toEqual(true); const journalUpdates = journal.flush(); expect(journalUpdates.l1ToL2MessageChecks).toEqual([ - expect.objectContaining({ leafIndex: leafIndex, msgHash: utxo, exists: true }), + expect.objectContaining({ leafIndex: leafIndex, msgHash, exists: true }), ]); }); it('Should maintain nullifiers', async () => { @@ -150,11 +149,11 @@ describe('journal', () => { }); it('Should maintain l1 messages', () => { const recipient = EthAddress.fromField(new Fr(1)); - const utxo = new Fr(2); - journal.writeL1Message(recipient, utxo); + const msgHash = new Fr(2); + journal.writeL1Message(recipient, msgHash); const journalUpdates = journal.flush(); - expect(journalUpdates.newL1Messages).toEqual([{ recipient, content: utxo }]); + expect(journalUpdates.newL1Messages).toEqual([{ recipient, content: msgHash }]); }); }); diff --git a/yarn-project/simulator/src/avm/journal/journal.ts b/yarn-project/simulator/src/avm/journal/journal.ts index 5972aeb391e0..5c21dd175a3b 100644 --- a/yarn-project/simulator/src/avm/journal/journal.ts +++ b/yarn-project/simulator/src/avm/journal/journal.ts @@ -16,6 +16,7 @@ import { type TracedNullifierCheck, type TracedPublicStorageRead, type TracedPublicStorageWrite, + type TracedUnencryptedL2Log, } from './trace_types.js'; /** @@ -33,7 +34,7 @@ export type JournalData = { newL1Messages: L2ToL1Message[]; newLogs: UnencryptedL2Log[]; - + newLogsHashes: TracedUnencryptedL2Log[]; /** contract address -\> key -\> value */ currentStorageValue: Map>; }; @@ -171,24 +172,11 @@ export class AvmPersistableStateManager { * @returns exists - whether the message exists in the L1 to L2 Messages tree */ public async checkL1ToL2MessageExists(msgHash: Fr, msgLeafIndex: Fr): Promise { - let exists = false; - try { - // The following 2 values are used to compute a message nullifier. Given that here we do not care about getting - // non-nullified messages we can just pass in random values and the nullifier check will effectively be ignored - // (no nullifier will be found). - const ignoredContractAddress = AztecAddress.random(); - const ignoredSecret = Fr.random(); - const gotMessage = await this.hostStorage.commitmentsDb.getL1ToL2MembershipWitness( - ignoredContractAddress, - msgHash, - ignoredSecret, - ); - exists = gotMessage !== undefined && gotMessage.index == msgLeafIndex.toBigInt(); - } catch { - // error getting message - doesn't exist! - exists = false; - } - this.log.debug(`l1ToL2Messages(${msgHash})@${msgLeafIndex} ?? exists: ${exists}.`); + const valueAtIndex = await this.hostStorage.commitmentsDb.getL1ToL2LeafValue(msgLeafIndex.toBigInt()); + const exists = valueAtIndex?.equals(msgHash) ?? false; + this.log.debug( + `l1ToL2Messages(@${msgLeafIndex}) ?? exists: ${exists}, expected: ${msgHash}, found: ${valueAtIndex}.`, + ); this.trace.traceL1ToL2MessageCheck(msgHash, msgLeafIndex, exists); return Promise.resolve(exists); } @@ -206,13 +194,13 @@ export class AvmPersistableStateManager { public writeLog(contractAddress: Fr, event: Fr, log: Fr[]) { this.log.debug(`UnencryptedL2Log(${contractAddress}) += event ${event} with ${log.length} fields.`); - this.newLogs.push( - new UnencryptedL2Log( - AztecAddress.fromField(contractAddress), - EventSelector.fromField(event), - Buffer.concat(log.map(f => f.toBuffer())), - ), + const L2log = new UnencryptedL2Log( + AztecAddress.fromField(contractAddress), + EventSelector.fromField(event), + Buffer.concat(log.map(f => f.toBuffer())), ); + this.newLogs.push(L2log); + this.trace.traceNewLog(Fr.fromBuffer(L2log.hash())); } /** @@ -252,6 +240,7 @@ export class AvmPersistableStateManager { l1ToL2MessageChecks: this.trace.l1ToL2MessageChecks, newL1Messages: this.newL1Messages, newLogs: this.newLogs, + newLogsHashes: this.trace.newLogsHashes, currentStorageValue: this.publicStorage.getCache().cachePerContract, storageReads: this.trace.publicStorageReads, storageWrites: this.trace.publicStorageWrites, diff --git a/yarn-project/simulator/src/avm/journal/trace.ts b/yarn-project/simulator/src/avm/journal/trace.ts index aa88454f9b7f..8cb115eae675 100644 --- a/yarn-project/simulator/src/avm/journal/trace.ts +++ b/yarn-project/simulator/src/avm/journal/trace.ts @@ -8,6 +8,7 @@ import { type TracedNullifierCheck, type TracedPublicStorageRead, type TracedPublicStorageWrite, + type TracedUnencryptedL2Log, } from './trace_types.js'; export class WorldStateAccessTrace { @@ -21,6 +22,7 @@ export class WorldStateAccessTrace { public nullifierChecks: TracedNullifierCheck[] = []; public newNullifiers: TracedNullifier[] = []; public l1ToL2MessageChecks: TracedL1toL2MessageCheck[] = []; + public newLogsHashes: TracedUnencryptedL2Log[] = []; //public contractCalls: TracedContractCall[] = []; //public archiveChecks: TracedArchiveLeafCheck[] = []; @@ -133,6 +135,15 @@ export class WorldStateAccessTrace { this.incrementAccessCounter(); } + public traceNewLog(logHash: Fr) { + const traced: TracedUnencryptedL2Log = { + logHash, + counter: new Fr(this.accessCounter), + }; + this.newLogsHashes.push(traced); + this.incrementAccessCounter(); + } + private incrementAccessCounter() { this.accessCounter++; } @@ -155,6 +166,7 @@ export class WorldStateAccessTrace { this.nullifierChecks = this.nullifierChecks.concat(incomingTrace.nullifierChecks); this.newNullifiers = this.newNullifiers.concat(incomingTrace.newNullifiers); this.l1ToL2MessageChecks = this.l1ToL2MessageChecks.concat(incomingTrace.l1ToL2MessageChecks); + this.newLogsHashes = this.newLogsHashes.concat(incomingTrace.newLogsHashes); // it is assumed that the incoming trace was initialized with this as parent, so accept counter this.accessCounter = incomingTrace.accessCounter; } diff --git a/yarn-project/simulator/src/avm/journal/trace_types.ts b/yarn-project/simulator/src/avm/journal/trace_types.ts index 81de24729e73..3c93649cefdb 100644 --- a/yarn-project/simulator/src/avm/journal/trace_types.ts +++ b/yarn-project/simulator/src/avm/journal/trace_types.ts @@ -73,6 +73,13 @@ export type TracedL1toL2MessageCheck = { //endLifetime: Fr; }; +export type TracedUnencryptedL2Log = { + //callPointer: Fr; + logHash: Fr; + counter: Fr; + //endLifetime: Fr; +}; + //export type TracedArchiveLeafCheck = { // leafIndex: Fr; // leaf: Fr; diff --git a/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts b/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts index 5eac2f364f49..88c7cadd1384 100644 --- a/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts @@ -8,12 +8,7 @@ import { type CommitmentsDB } from '../../index.js'; import { type AvmContext } from '../avm_context.js'; import { Field, Uint8 } from '../avm_memory_types.js'; import { InstructionExecutionError } from '../errors.js'; -import { - initContext, - initExecutionEnvironment, - initHostStorage, - initL1ToL2MessageOracleInput, -} from '../fixtures/index.js'; +import { initContext, initExecutionEnvironment, initHostStorage } from '../fixtures/index.js'; import { AvmPersistableStateManager } from '../journal/journal.js'; import { EmitNoteHash, @@ -348,7 +343,7 @@ describe('Accrued Substate', () => { // mock commitments db to show message exists const commitmentsDb = mock(); - commitmentsDb.getL1ToL2MembershipWitness.mockResolvedValue(initL1ToL2MessageOracleInput(leafIndex.toBigInt())); + commitmentsDb.getL1ToL2LeafValue.mockResolvedValue(msgHash.toFr()); const hostStorage = initHostStorage({ commitmentsDb }); context = initContext({ persistableState: new AvmPersistableStateManager(hostStorage) }); @@ -356,7 +351,6 @@ describe('Accrued Substate', () => { context.machineState.memory.set(msgLeafIndexOffset, leafIndex); await new L1ToL2MessageExists(/*indirect=*/ 0, msgHashOffset, msgLeafIndexOffset, existsOffset).execute(context); - // never created, doesn't exist! const exists = context.machineState.memory.getAs(existsOffset); expect(exists).toEqual(new Uint8(1)); @@ -365,6 +359,32 @@ describe('Accrued Substate', () => { expect.objectContaining({ leafIndex: leafIndex.toFr(), msgHash: msgHash.toFr(), exists: true }), ]); }); + + it('Should correctly show false when another L1ToL2 message exists at that index', async () => { + const msgHash = new Field(69n); + const leafIndex = new Field(42n); + const msgHashOffset = 0; + const msgLeafIndexOffset = 1; + const existsOffset = 2; + + const commitmentsDb = mock(); + commitmentsDb.getL1ToL2LeafValue.mockResolvedValue(Fr.ZERO); + const hostStorage = initHostStorage({ commitmentsDb }); + context = initContext({ persistableState: new AvmPersistableStateManager(hostStorage) }); + + context.machineState.memory.set(msgHashOffset, msgHash); + context.machineState.memory.set(msgLeafIndexOffset, leafIndex); + await new L1ToL2MessageExists(/*indirect=*/ 0, msgHashOffset, msgLeafIndexOffset, existsOffset).execute(context); + + // never created, doesn't exist! + const exists = context.machineState.memory.getAs(existsOffset); + expect(exists).toEqual(new Uint8(0)); + + const journalState = context.persistableState.flush(); + expect(journalState.l1ToL2MessageChecks).toEqual([ + expect.objectContaining({ leafIndex: leafIndex.toFr(), msgHash: msgHash.toFr(), exists: false }), + ]); + }); }); describe('EmitUnencryptedLog', () => { diff --git a/yarn-project/simulator/src/avm/opcodes/arithmetic.ts b/yarn-project/simulator/src/avm/opcodes/arithmetic.ts index 137b92ab878a..e55ba9fb1e53 100644 --- a/yarn-project/simulator/src/avm/opcodes/arithmetic.ts +++ b/yarn-project/simulator/src/avm/opcodes/arithmetic.ts @@ -23,7 +23,7 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst context.machineState.incrementPc(); } - protected gasCost(memoryOps: Partial) { + protected override gasCost(memoryOps: Partial) { const baseGasCost = getGasCostForTypeTag(this.inTag, getBaseGasCost(this.opcode)); const memoryGasCost = getMemoryGasCost(memoryOps); return sumGas(baseGasCost, memoryGasCost); @@ -102,7 +102,7 @@ export class FieldDiv extends Instruction { context.machineState.incrementPc(); } - protected gasCost(memoryOps: Partial) { + protected override gasCost(memoryOps: Partial) { const baseGasCost = getGasCostForTypeTag(TypeTag.FIELD, getBaseGasCost(this.opcode)); const memoryGasCost = getMemoryGasCost(memoryOps); return sumGas(baseGasCost, memoryGasCost); diff --git a/yarn-project/simulator/src/avm/opcodes/context_getters.ts b/yarn-project/simulator/src/avm/opcodes/context_getters.ts index e07948e46575..d1fbc639771e 100644 --- a/yarn-project/simulator/src/avm/opcodes/context_getters.ts +++ b/yarn-project/simulator/src/avm/opcodes/context_getters.ts @@ -7,7 +7,7 @@ export class L2GasLeft extends GetterInstruction { static type: string = 'L2GASLEFT'; static readonly opcode: Opcode = Opcode.L2GASLEFT; - // TODO(@spalladino) Yellow paper specifies that the value should be an Uint32, not a Field. + // TODO(@spalladino) Protocol specs specifies that the value should be an Uint32, not a Field. protected getValue(context: AvmContext): MemoryValue { return new Field(context.machineState.l2GasLeft); } diff --git a/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts b/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts index be9505d4e191..96818cd7a71c 100644 --- a/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts @@ -8,7 +8,6 @@ import { FeePerDAGas, FeePerL1Gas, FeePerL2Gas, - Origin, Portal, Sender, StorageAddress, @@ -21,7 +20,6 @@ type EnvInstruction = | typeof FeePerL1Gas | typeof FeePerL2Gas | typeof FeePerDAGas - | typeof Origin | typeof Sender | typeof StorageAddress | typeof Address; @@ -30,7 +28,6 @@ describe.each([ [FeePerL1Gas, 'feePerL1Gas'], [FeePerL2Gas, 'feePerL2Gas'], [FeePerDAGas, 'feePerDaGas'], - [Origin, 'origin'], [Sender, 'sender'], [StorageAddress, 'storageAddress'], [Address, 'address'], diff --git a/yarn-project/simulator/src/avm/opcodes/environment_getters.ts b/yarn-project/simulator/src/avm/opcodes/environment_getters.ts index 9f179841fcbe..b105fd20d776 100644 --- a/yarn-project/simulator/src/avm/opcodes/environment_getters.ts +++ b/yarn-project/simulator/src/avm/opcodes/environment_getters.ts @@ -41,15 +41,6 @@ export class Sender extends EnvironmentGetterInstruction { } } -export class Origin extends EnvironmentGetterInstruction { - static type: string = 'ORIGIN'; - static readonly opcode: Opcode = Opcode.ORIGIN; - - protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return env.origin; - } -} - export class FeePerL1Gas extends EnvironmentGetterInstruction { static type: string = 'FEEPERL1GAS'; static readonly opcode: Opcode = Opcode.FEEPERL1GAS; diff --git a/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts b/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts index b8e508fa0026..29c6626fa8d0 100644 --- a/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts @@ -6,7 +6,7 @@ import { mock } from 'jest-mock-extended'; import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from '../../index.js'; import { markBytecodeAsAvm } from '../../public/transitional_adaptors.js'; import { type AvmContext } from '../avm_context.js'; -import { Field, Uint8 } from '../avm_memory_types.js'; +import { Field, Uint8, Uint32 } from '../avm_memory_types.js'; import { adjustCalldataIndex, initContext } from '../fixtures/index.js'; import { HostStorage } from '../journal/host_storage.js'; import { AvmPersistableStateManager } from '../journal/journal.js'; @@ -36,7 +36,7 @@ describe('External Calls', () => { ...Buffer.from('12345678', 'hex'), // gasOffset ...Buffer.from('a2345678', 'hex'), // addrOffset ...Buffer.from('b2345678', 'hex'), // argsOffset - ...Buffer.from('c2345678', 'hex'), // argsSize + ...Buffer.from('c2345678', 'hex'), // argsSizeOffset ...Buffer.from('d2345678', 'hex'), // retOffset ...Buffer.from('e2345678', 'hex'), // retSize ...Buffer.from('f2345678', 'hex'), // successOffset @@ -47,7 +47,7 @@ describe('External Calls', () => { /*gasOffset=*/ 0x12345678, /*addrOffset=*/ 0xa2345678, /*argsOffset=*/ 0xb2345678, - /*argsSize=*/ 0xc2345678, + /*argsSizeOffset=*/ 0xc2345678, /*retOffset=*/ 0xd2345678, /*retSize=*/ 0xe2345678, /*successOffset=*/ 0xf2345678, @@ -68,6 +68,7 @@ describe('External Calls', () => { const argsOffset = 4; const args = [new Field(1n), new Field(2n), new Field(3n)]; const argsSize = args.length; + const argsSizeOffset = 20; const retOffset = 8; const retSize = 2; const successOffset = 7; @@ -93,6 +94,7 @@ describe('External Calls', () => { context.machineState.memory.set(1, new Field(l2Gas)); context.machineState.memory.set(2, new Field(daGas)); context.machineState.memory.set(3, new Field(addr)); + context.machineState.memory.set(argsSizeOffset, new Uint32(argsSize)); context.machineState.memory.setSlice(4, args); jest .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') @@ -103,7 +105,7 @@ describe('External Calls', () => { gasOffset, addrOffset, argsOffset, - argsSize, + argsSizeOffset, retOffset, retSize, successOffset, @@ -137,7 +139,7 @@ describe('External Calls', () => { it('Should refuse to execute a call if not enough gas', async () => { const gasOffset = 0; - const l1Gas = 1e12; // We request more gas than what we have + const l1Gas = 1e9; // We request more gas than what we have const l2Gas = 2e6; const daGas = 3e6; const addrOffset = 3; @@ -145,6 +147,7 @@ describe('External Calls', () => { const argsOffset = 4; const args = [new Field(1n), new Field(2n), new Field(3n)]; const argsSize = args.length; + const argsSizeOffset = 20; const retOffset = 8; const retSize = 2; const successOffset = 7; @@ -153,6 +156,7 @@ describe('External Calls', () => { context.machineState.memory.set(1, new Field(l2Gas)); context.machineState.memory.set(2, new Field(daGas)); context.machineState.memory.set(3, new Field(addr)); + context.machineState.memory.set(argsSizeOffset, new Uint32(argsSize)); context.machineState.memory.setSlice(4, args); jest @@ -164,7 +168,7 @@ describe('External Calls', () => { gasOffset, addrOffset, argsOffset, - argsSize, + argsSizeOffset, retOffset, retSize, successOffset, @@ -183,7 +187,7 @@ describe('External Calls', () => { ...Buffer.from('12345678', 'hex'), // gasOffset ...Buffer.from('a2345678', 'hex'), // addrOffset ...Buffer.from('b2345678', 'hex'), // argsOffset - ...Buffer.from('c2345678', 'hex'), // argsSize + ...Buffer.from('c2345678', 'hex'), // argsSizeOffset ...Buffer.from('d2345678', 'hex'), // retOffset ...Buffer.from('e2345678', 'hex'), // retSize ...Buffer.from('f2345678', 'hex'), // successOffset @@ -194,7 +198,7 @@ describe('External Calls', () => { /*gasOffset=*/ 0x12345678, /*addrOffset=*/ 0xa2345678, /*argsOffset=*/ 0xb2345678, - /*argsSize=*/ 0xc2345678, + /*argsSizeOffset=*/ 0xc2345678, /*retOffset=*/ 0xd2345678, /*retSize=*/ 0xe2345678, /*successOffset=*/ 0xf2345678, @@ -214,12 +218,14 @@ describe('External Calls', () => { const args = [new Field(1n), new Field(2n), new Field(3n)]; const argsSize = args.length; + const argsSizeOffset = 20; const retOffset = 8; const retSize = 2; const successOffset = 7; context.machineState.memory.set(0, gas); context.machineState.memory.set(1, addr); + context.machineState.memory.set(argsSizeOffset, new Uint32(argsSize)); context.machineState.memory.setSlice(2, args); const otherContextInstructions: Instruction[] = [ @@ -243,7 +249,7 @@ describe('External Calls', () => { gasOffset, addrOffset, argsOffset, - argsSize, + argsSizeOffset, retOffset, retSize, successOffset, @@ -304,11 +310,9 @@ describe('External Calls', () => { }); it('Should return data and revert from the revert opcode', async () => { - const returnData = [new Fr(1n), new Fr(2n), new Fr(3n)]; + const returnData = [...'assert message'].flatMap(c => new Field(c.charCodeAt(0))); - context.machineState.memory.set(0, new Field(1n)); - context.machineState.memory.set(1, new Field(2n)); - context.machineState.memory.set(2, new Field(3n)); + context.machineState.memory.setSlice(0, returnData); const instruction = new Revert(/*indirect=*/ 0, /*returnOffset=*/ 0, returnData.length); await instruction.execute(context); @@ -316,7 +320,8 @@ describe('External Calls', () => { expect(context.machineState.halted).toBe(true); expect(context.machineState.getResults()).toEqual({ reverted: true, - output: returnData, + revertReason: new Error('Reverted with output: assert message'), + output: returnData.map(f => f.toFr()), }); }); }); diff --git a/yarn-project/simulator/src/avm/opcodes/external_calls.ts b/yarn-project/simulator/src/avm/opcodes/external_calls.ts index 2d25634055ab..f3f982f792f5 100644 --- a/yarn-project/simulator/src/avm/opcodes/external_calls.ts +++ b/yarn-project/simulator/src/avm/opcodes/external_calls.ts @@ -36,7 +36,7 @@ abstract class ExternalCall extends Instruction { private gasOffset: number /* Unused due to no formal gas implementation at this moment */, private addrOffset: number, private argsOffset: number, - private argsSize: number, + private argsSizeOffset: number, private retOffset: number, private retSize: number, private successOffset: number, @@ -50,20 +50,23 @@ abstract class ExternalCall extends Instruction { public async execute(context: AvmContext) { const memory = context.machineState.memory.track(this.type); - const [gasOffset, addrOffset, argsOffset, retOffset, successOffset] = Addressing.fromWire(this.indirect).resolve( - [this.gasOffset, this.addrOffset, this.argsOffset, this.retOffset, this.successOffset], + const [gasOffset, addrOffset, argsOffset, argsSizeOffset, retOffset, successOffset] = Addressing.fromWire( + this.indirect, + ).resolve( + [this.gasOffset, this.addrOffset, this.argsOffset, this.argsSizeOffset, this.retOffset, this.successOffset], memory, ); const callAddress = memory.getAs(addrOffset); - const calldata = memory.getSlice(argsOffset, this.argsSize).map(f => f.toFr()); + const calldataSize = memory.get(argsSizeOffset).toNumber(); + const calldata = memory.getSlice(argsOffset, calldataSize).map(f => f.toFr()); const l1Gas = memory.get(gasOffset).toNumber(); const l2Gas = memory.getAs(gasOffset + 1).toNumber(); const daGas = memory.getAs(gasOffset + 2).toNumber(); const functionSelector = memory.getAs(this.temporaryFunctionSelectorOffset).toFr(); const allocatedGas = { l1Gas, l2Gas, daGas }; - const memoryOperations = { reads: this.argsSize + 5, writes: 1 + this.retSize, indirect: this.indirect }; + const memoryOperations = { reads: calldataSize + 6, writes: 1 + this.retSize, indirect: this.indirect }; const totalGas = sumGas(this.gasCost(memoryOperations), allocatedGas); context.machineState.consumeGas(totalGas); @@ -119,7 +122,7 @@ abstract class ExternalCall extends Instruction { context.machineState.incrementPc(); } - public abstract get type(): 'CALL' | 'STATICCALL'; + public abstract override get type(): 'CALL' | 'STATICCALL'; } export class Call extends ExternalCall { diff --git a/yarn-project/simulator/src/avm/opcodes/memory.ts b/yarn-project/simulator/src/avm/opcodes/memory.ts index 81eb5fd8ea7e..770f4da5b3ab 100644 --- a/yarn-project/simulator/src/avm/opcodes/memory.ts +++ b/yarn-project/simulator/src/avm/opcodes/memory.ts @@ -46,7 +46,7 @@ export class Set extends Instruction { } /** We need to use a custom serialize function because of the variable length of the value. */ - public serialize(): Buffer { + public override serialize(): Buffer { const format: OperandType[] = [ ...Set.wireFormatBeforeConst, getOperandTypeFromInTag(this.inTag), @@ -56,7 +56,7 @@ export class Set extends Instruction { } /** We need to use a custom deserialize function because of the variable length of the value. */ - public static deserialize(this: typeof Set, buf: BufferCursor | Buffer): Set { + public static override deserialize(this: typeof Set, buf: BufferCursor | Buffer): Set { if (buf instanceof Buffer) { buf = new BufferCursor(buf); } @@ -217,7 +217,7 @@ export class CalldataCopy extends Instruction { context.machineState.incrementPc(); } - protected gasCost(memoryOps: Partial = {}) { + protected override gasCost(memoryOps: Partial = {}) { const baseGasCost = mulGas(getBaseGasCost(this.opcode), this.copySize); const memoryGasCost = getMemoryGasCost(memoryOps); return sumGas(baseGasCost, memoryGasCost); diff --git a/yarn-project/simulator/src/avm/opcodes/storage.ts b/yarn-project/simulator/src/avm/opcodes/storage.ts index c72541c0572e..62c3d180b0f4 100644 --- a/yarn-project/simulator/src/avm/opcodes/storage.ts +++ b/yarn-project/simulator/src/avm/opcodes/storage.ts @@ -27,7 +27,7 @@ abstract class BaseStorageInstruction extends Instruction { super(); } - protected gasCost(memoryOps: Partial): Gas { + protected override gasCost(memoryOps: Partial): Gas { const baseGasCost = mulGas(getBaseGasCost(this.opcode), this.size); const memoryGasCost = getMemoryGasCost(memoryOps); return sumGas(baseGasCost, memoryGasCost); diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts index 29d7357a904b..6a95dac7fed4 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts @@ -33,7 +33,6 @@ import { NoteHashExists, NullifierExists, Or, - Origin, Portal, Return, Revert, @@ -82,7 +81,6 @@ const INSTRUCTION_SET = () => [Cast.opcode, Cast], [Address.opcode, Address], [StorageAddress.opcode, StorageAddress], - [Origin.opcode, Origin], [Sender.opcode, Sender], [Portal.opcode, Portal], [FeePerL1Gas.opcode, FeePerL1Gas], diff --git a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts index c2e092e1a5b9..6f5bb70eb41b 100644 --- a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts @@ -3,7 +3,7 @@ import { strict as assert } from 'assert'; import { BufferCursor } from './buffer_cursor.js'; /** - * All AVM opcodes. (Keep in sync with cpp counterpart code avm_opcode.hpp). + * All AVM opcodes. (Keep in sync with cpp counterpart code avm_opcode.hpp and rs in opcodes.rs). * Source: https://yp-aztec.netlify.app/docs/public-vm/instruction-set */ export enum Opcode { @@ -26,7 +26,6 @@ export enum Opcode { // Execution environment ADDRESS, STORAGEADDRESS, - ORIGIN, SENDER, PORTAL, FEEPERL1GAS, diff --git a/yarn-project/simulator/src/client/client_execution_context.ts b/yarn-project/simulator/src/client/client_execution_context.ts index 522966631adc..5d7d33375b47 100644 --- a/yarn-project/simulator/src/client/client_execution_context.ts +++ b/yarn-project/simulator/src/client/client_execution_context.ts @@ -14,7 +14,6 @@ import { CallContext, FunctionData, FunctionSelector, - GasSettings, type Header, NoteHashReadRequestMembershipWitness, PublicCallRequest, @@ -65,21 +64,21 @@ export class ClientExecutionContext extends ViewDataOracle { private enqueuedPublicFunctionCalls: PublicCallRequest[] = []; constructor( - protected readonly contractAddress: AztecAddress, + contractAddress: AztecAddress, private readonly argsHash: Fr, private readonly txContext: TxContext, private readonly callContext: CallContext, /** Header of a block whose state is used during private execution (not the block the transaction is included in). */ protected readonly historicalHeader: Header, /** List of transient auth witnesses to be used during this simulation */ - protected readonly authWitnesses: AuthWitness[], + authWitnesses: AuthWitness[], private readonly packedValuesCache: PackedValuesCache, private readonly noteCache: ExecutionNoteCache, - protected readonly db: DBOracle, + db: DBOracle, private readonly curve: Grumpkin, private node: AztecNode, protected sideEffectCounter: number = 0, - protected log = createDebugLogger('aztec:simulator:client_execution_context'), + log = createDebugLogger('aztec:simulator:client_execution_context'), ) { super(contractAddress, authWitnesses, db, node, log); } @@ -172,10 +171,10 @@ export class ClientExecutionContext extends ViewDataOracle { } /** - * Pack the given arguments. + * Pack the given array of arguments. * @param args - Arguments to pack */ - public packArguments(args: Fr[]): Promise { + public override packArgumentsArray(args: Fr[]): Promise { return Promise.resolve(this.packedValuesCache.pack(args)); } @@ -183,7 +182,7 @@ export class ClientExecutionContext extends ViewDataOracle { * Pack the given returns. * @param returns - Returns to pack */ - public packReturns(returns: Fr[]): Promise { + public override packReturns(returns: Fr[]): Promise { return Promise.resolve(this.packedValuesCache.pack(returns)); } @@ -191,7 +190,7 @@ export class ClientExecutionContext extends ViewDataOracle { * Unpack the given returns. * @param returnsHash - Returns hash to unpack */ - public unpackReturns(returnsHash: Fr): Promise { + public override unpackReturns(returnsHash: Fr): Promise { return Promise.resolve(this.packedValuesCache.unpack(returnsHash)); } @@ -215,7 +214,7 @@ export class ClientExecutionContext extends ViewDataOracle { * @param status - The status of notes to fetch. * @returns Array of note data. */ - public async getNotes( + public override async getNotes( storageSlot: Fr, numSelects: number, selectByIndexes: number[], @@ -282,7 +281,7 @@ export class ClientExecutionContext extends ViewDataOracle { * @param innerNoteHash - The inner note hash of the new note. * @returns */ - public notifyCreatedNote(storageSlot: Fr, noteTypeId: Fr, noteItems: Fr[], innerNoteHash: Fr) { + public override notifyCreatedNote(storageSlot: Fr, noteTypeId: Fr, noteItems: Fr[], innerNoteHash: Fr) { const note = new Note(noteItems); this.noteCache.addNewNote({ contractAddress: this.callContext.storageContractAddress, @@ -305,7 +304,7 @@ export class ClientExecutionContext extends ViewDataOracle { * @param innerNullifier - The pending nullifier to add in the list (not yet siloed by contract address). * @param innerNoteHash - The inner note hash of the new note. */ - public notifyNullifiedNote(innerNullifier: Fr, innerNoteHash: Fr) { + public override notifyNullifiedNote(innerNullifier: Fr, innerNoteHash: Fr) { this.noteCache.nullifyNote(this.callContext.storageContractAddress, innerNullifier, innerNoteHash); return Promise.resolve(); } @@ -318,22 +317,31 @@ export class ClientExecutionContext extends ViewDataOracle { * @param publicKey - The public key of the account that can decrypt the log. * @param log - The log contents. */ - public emitEncryptedLog(contractAddress: AztecAddress, storageSlot: Fr, noteTypeId: Fr, publicKey: Point, log: Fr[]) { + public override emitEncryptedLog( + contractAddress: AztecAddress, + storageSlot: Fr, + noteTypeId: Fr, + publicKey: Point, + log: Fr[], + ) { const note = new Note(log); const l1NotePayload = new L1NotePayload(note, contractAddress, storageSlot, noteTypeId); const taggedNote = new TaggedNote(l1NotePayload); const encryptedNote = taggedNote.toEncryptedBuffer(publicKey, this.curve); - this.encryptedLogs.push(new EncryptedL2Log(encryptedNote)); + const encryptedLog = new EncryptedL2Log(encryptedNote); + this.encryptedLogs.push(encryptedLog); + return Fr.fromBuffer(encryptedLog.hash()); } /** * Emit an unencrypted log. * @param log - The unencrypted log to be emitted. */ - public emitUnencryptedLog(log: UnencryptedL2Log) { + public override emitUnencryptedLog(log: UnencryptedL2Log) { this.unencryptedLogs.push(log); const text = log.toHumanReadable(); this.log.verbose(`Emitted unencrypted log: "${text.length > 100 ? text.slice(0, 100) + '...' : text}"`); + return Fr.fromBuffer(log.hash()); } #checkValidStaticCall(childExecutionResult: ExecutionResult) { @@ -358,7 +366,7 @@ export class ClientExecutionContext extends ViewDataOracle { * @param isStaticCall - Whether the call is a delegate call. * @returns The execution result. */ - async callPrivateFunction( + override async callPrivateFunction( targetContractAddress: AztecAddress, functionSelector: FunctionSelector, argsHash: Fr, @@ -427,7 +435,7 @@ export class ClientExecutionContext extends ViewDataOracle { * @param isStaticCall - Whether the call is a static call. * @returns The public call stack item with the request information. */ - public async enqueuePublicFunctionCall( + public override async enqueuePublicFunctionCall( targetContractAddress: AztecAddress, functionSelector: FunctionSelector, argsHash: Fr, @@ -484,17 +492,17 @@ export class ClientExecutionContext extends ViewDataOracle { isStaticCall = false, ) { const portalContractAddress = await this.db.getPortalContractAddress(targetContractAddress); - const transactionFee = Fr.ZERO; // TODO(palla/gas-in-circuits) return new CallContext( isDelegateCall ? this.callContext.msgSender : this.contractAddress, isDelegateCall ? this.contractAddress : targetContractAddress, portalContractAddress, FunctionSelector.fromNameAndParameters(targetArtifact.name, targetArtifact.parameters), + this.callContext.gasLeft, // TODO(palla/gas): We should deduct DA and L1 gas used for the derived context isDelegateCall, isStaticCall, startSideEffectCounter, - GasSettings.empty(), // TODO(palla/gas-in-circuits) - transactionFee, + this.callContext.gasSettings, + this.callContext.transactionFee, ); } @@ -503,7 +511,7 @@ export class ClientExecutionContext extends ViewDataOracle { * @param startStorageSlot - The starting storage slot. * @param numberOfElements - Number of elements to read from the starting storage slot. */ - public async storageRead(startStorageSlot: Fr, numberOfElements: number): Promise { + public override async storageRead(startStorageSlot: Fr, numberOfElements: number): Promise { // TODO(#4320): This is a hack to work around not having directly access to the public data tree but // still having access to the witnesses const bn = await this.db.getBlockNumber(); diff --git a/yarn-project/simulator/src/client/execution_result.ts b/yarn-project/simulator/src/client/execution_result.ts index 5118b28d6070..845386e98076 100644 --- a/yarn-project/simulator/src/client/execution_result.ts +++ b/yarn-project/simulator/src/client/execution_result.ts @@ -4,7 +4,6 @@ import { type PrivateCallStackItem, type PublicCallRequest, } from '@aztec/circuits.js'; -import { type DecodedReturn } from '@aztec/foundation/abi'; import { type Fr } from '@aztec/foundation/fields'; import { type ACVMField } from '../acvm/index.js'; @@ -40,20 +39,20 @@ export interface ExecutionResult { // Needed when we enable chained txs. The new notes can be cached and used in a later transaction. /** The notes created in the executed function. */ newNotes: NoteAndSlot[]; - /** The decoded return values of the executed function. */ - returnValues: DecodedReturn; + /** The raw return values of the executed function. */ + returnValues: Fr[]; /** The nested executions. */ nestedExecutions: this[]; /** Enqueued public function execution requests to be picked up by the sequencer. */ enqueuedPublicFunctionCalls: PublicCallRequest[]; /** * Encrypted logs emitted during execution of this function call. - * Note: These are preimages to `encryptedLogsHash`. + * Note: These are preimages to `encryptedLogsHashes`. */ encryptedLogs: EncryptedFunctionL2Logs; /** * Unencrypted logs emitted during execution of this function call. - * Note: These are preimages to `unencryptedLogsHash`. + * Note: These are preimages to `unencryptedLogsHashes`. */ unencryptedLogs: UnencryptedFunctionL2Logs; } diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index df4257032b71..512060e99486 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -116,6 +116,7 @@ describe('Private Execution test suite', () => { txContext: TxContext.from({ ...txContextFields, ...txContext }), packedArguments: [packedArguments], authWitnesses: [], + gasSettings: GasSettings.default(), }); return acirSimulator.run(txRequest, artifact, contractAddress, portalContractAddress, msgSender); @@ -432,7 +433,7 @@ describe('Private Execution test suite', () => { const artifact = getFunctionArtifact(ChildContractArtifact, 'value'); const result = await runSimulator({ args: [initialValue], artifact }); - expect(result.returnValues).toEqual([initialValue + privateIncrement]); + expect(result.returnValues).toEqual([new Fr(initialValue + privateIncrement)]); }); it('parent should call child', async () => { @@ -451,12 +452,12 @@ describe('Private Execution test suite', () => { const args = [childAddress, childSelector]; const result = await runSimulator({ args, artifact: parentArtifact }); - expect(result.returnValues).toEqual([privateIncrement]); + expect(result.returnValues).toEqual([new Fr(privateIncrement)]); expect(oracle.getFunctionArtifact.mock.calls[0]).toEqual([childAddress, childSelector]); expect(oracle.getPortalContractAddress.mock.calls[0]).toEqual([childAddress]); expect(result.nestedExecutions).toHaveLength(1); - expect(result.nestedExecutions[0].returnValues).toEqual([privateIncrement]); + expect(result.nestedExecutions[0].returnValues).toEqual([new Fr(privateIncrement)]); // check that Aztec.nr calculated the call stack item hash like cpp does const expectedCallStackItemHash = result.nestedExecutions[0].callStackItem.hash(); @@ -485,12 +486,12 @@ describe('Private Execution test suite', () => { logger.info(`Calling testCodeGen function`); const result = await runSimulator({ args, artifact: testCodeGenArtifact }); - expect(result.returnValues).toEqual([argsHash.toBigInt()]); + expect(result.returnValues).toEqual([argsHash]); }); it('test function should be callable through autogenerated interface', async () => { const testAddress = AztecAddress.random(); - const parentArtifact = getFunctionArtifact(ImportTestContractArtifact, 'main'); + const parentArtifact = getFunctionArtifact(ImportTestContractArtifact, 'main_contract'); const testCodeGenSelector = FunctionSelector.fromNameAndParameters( testCodeGenArtifact.name, testCodeGenArtifact.parameters, @@ -503,11 +504,11 @@ describe('Private Execution test suite', () => { const args = [testAddress]; const result = await runSimulator({ args, artifact: parentArtifact }); - expect(result.returnValues).toEqual([argsHash.toBigInt()]); + expect(result.returnValues).toEqual([argsHash]); expect(oracle.getFunctionArtifact.mock.calls[0]).toEqual([testAddress, testCodeGenSelector]); expect(oracle.getPortalContractAddress.mock.calls[0]).toEqual([testAddress]); expect(result.nestedExecutions).toHaveLength(1); - expect(result.nestedExecutions[0].returnValues).toEqual([argsHash.toBigInt()]); + expect(result.nestedExecutions[0].returnValues).toEqual([argsHash]); }); }); @@ -796,7 +797,8 @@ describe('Private Execution test suite', () => { const functionData = FunctionData.fromAbi(childContractArtifact); const transactionFee = new Fr(0); - const gasSettings = GasSettings.empty(); + const gasSettings = GasSettings.default(); + const gasLeft = gasSettings.getInitialAvailable(); const publicCallRequest = PublicCallRequest.from({ contractAddress: childAddress, @@ -807,6 +809,7 @@ describe('Private Execution test suite', () => { storageContractAddress: childAddress, portalContractAddress: childPortalContractAddress, functionSelector: childSelector, + gasLeft, isDelegateCall: false, isStaticCall: false, sideEffectCounter: 1, @@ -818,6 +821,7 @@ describe('Private Execution test suite', () => { storageContractAddress: parentAddress, portalContractAddress: EthAddress.ZERO, functionSelector: FunctionSelector.fromNameAndParameters(parentArtifact.name, parentArtifact.parameters), + gasLeft, isDelegateCall: false, isStaticCall: false, sideEffectCounter: 1, @@ -895,7 +899,7 @@ describe('Private Execution test suite', () => { const readRequest = sideEffectArrayToValueArray(result.callStackItem.publicInputs.noteHashReadRequests)[0]; expect(readRequest).toEqual(innerNoteHash); - expect(result.returnValues).toEqual([amountToTransfer]); + expect(result.returnValues).toEqual([new Fr(amountToTransfer)]); const nullifier = result.callStackItem.publicInputs.newNullifiers[0]; const siloedNullifierSecretKey = computeSiloedNullifierSecretKey( @@ -970,7 +974,7 @@ describe('Private Execution test suite', () => { const readRequest = execGetThenNullify.callStackItem.publicInputs.noteHashReadRequests[0]; expect(readRequest.value).toEqual(innerNoteHash); - expect(execGetThenNullify.returnValues).toEqual([amountToTransfer]); + expect(execGetThenNullify.returnValues).toEqual([new Fr(amountToTransfer)]); const nullifier = execGetThenNullify.callStackItem.publicInputs.newNullifiers[0]; const siloedNullifierSecretKey = computeSiloedNullifierSecretKey( @@ -995,7 +999,7 @@ describe('Private Execution test suite', () => { const artifact = getFunctionArtifact(PendingNoteHashesContractArtifact, 'test_bad_get_then_insert_flat'); const args = [amountToTransfer, owner]; - await expect( + await expect(() => runSimulator({ args: args, artifact: artifact, @@ -1009,7 +1013,6 @@ describe('Private Execution test suite', () => { it('gets the public key for an address', async () => { // Tweak the contract artifact so we can extract return values const artifact = getFunctionArtifact(TestContractArtifact, 'get_public_key'); - artifact.returnTypes = [{ kind: 'array', length: 2, type: { kind: 'field' } }]; // Generate a partial address, pubkey, and resulting address const completeAddress = CompleteAddress.random(); @@ -1018,7 +1021,7 @@ describe('Private Execution test suite', () => { oracle.getCompleteAddress.mockResolvedValue(completeAddress); const result = await runSimulator({ artifact, args }); - expect(result.returnValues).toEqual([pubKey.x.toBigInt(), pubKey.y.toBigInt()]); + expect(result.returnValues).toEqual([pubKey.x, pubKey.y]); }); }); @@ -1029,7 +1032,9 @@ describe('Private Execution test suite', () => { const args = [2n, true]; oracle.getNotes.mockResolvedValue([]); - await expect(runSimulator({ artifact, args })).rejects.toThrow(`Assertion failed: Cannot return zero notes`); + await expect(() => runSimulator({ artifact, args })).rejects.toThrow( + `Assertion failed: Cannot return zero notes`, + ); }); }); @@ -1040,14 +1045,13 @@ describe('Private Execution test suite', () => { // Tweak the contract artifact so we can extract return values const artifact = getFunctionArtifact(TestContractArtifact, 'get_portal_contract_address'); - artifact.returnTypes = [{ kind: 'field' }]; const args = [aztecAddressToQuery.toField()]; // Overwrite the oracle return value oracle.getPortalContractAddress.mockResolvedValue(portalContractAddress); const result = await runSimulator({ artifact, args }); - expect(result.returnValues).toEqual([portalContractAddress.toField().value]); + expect(result.returnValues).toEqual([portalContractAddress.toField()]); }); it('this_address should return the current context address', async () => { @@ -1055,11 +1059,10 @@ describe('Private Execution test suite', () => { // Tweak the contract artifact so we can extract return values const artifact = getFunctionArtifact(TestContractArtifact, 'get_this_address'); - artifact.returnTypes = [{ kind: 'field' }]; // Overwrite the oracle return value const result = await runSimulator({ artifact, args: [], contractAddress }); - expect(result.returnValues).toEqual([contractAddress.toField().toBigInt()]); + expect(result.returnValues).toEqual([contractAddress.toField()]); }); it("this_portal_address should return the current context's portal address", async () => { @@ -1067,11 +1070,10 @@ describe('Private Execution test suite', () => { // Tweak the contract artifact so we can extract return values const artifact = getFunctionArtifact(TestContractArtifact, 'get_this_portal_address'); - artifact.returnTypes = [{ kind: 'field' }]; // Overwrite the oracle return value const result = await runSimulator({ artifact, args: [], portalContractAddress }); - expect(result.returnValues).toEqual([portalContractAddress.toField().toBigInt()]); + expect(result.returnValues).toEqual([portalContractAddress.toField()]); }); }); @@ -1081,7 +1083,7 @@ describe('Private Execution test suite', () => { let args: any[]; let artifact: FunctionArtifact; - beforeAll(() => { + beforeEach(() => { chainId = Fr.random(); version = Fr.random(); args = [chainId, version]; @@ -1090,15 +1092,15 @@ describe('Private Execution test suite', () => { oracle.getFunctionArtifact.mockImplementation(() => Promise.resolve(artifact)); }); - it('Private global vars are correctly set', () => { + it('Private global vars are correctly set', async () => { // Chain id and version set in tx context is the same as the ones we pass via args so this should not throw - expect(() => runSimulator({ artifact, msgSender: owner, args, txContext: { chainId, version } })).not.toThrow(); + await runSimulator({ artifact, msgSender: owner, args, txContext: { chainId, version } }); }); it('Throws when chainId is incorrectly set', async () => { // We set the chainId in the tx context to a different value than the one we pass via args so the simulator should throw const unexpectedChainId = Fr.random(); - await expect( + await expect(() => runSimulator({ artifact, msgSender: owner, args, txContext: { chainId: unexpectedChainId, version } }), ).rejects.toThrow('Invalid chain id'); }); @@ -1106,7 +1108,7 @@ describe('Private Execution test suite', () => { it('Throws when version is incorrectly set', async () => { // We set the version in the tx context to a different value than the one we pass via args so the simulator should throw const unexpectedVersion = Fr.random(); - await expect( + await expect(() => runSimulator({ artifact, msgSender: owner, args, txContext: { chainId, version: unexpectedVersion } }), ).rejects.toThrow('Invalid version'); }); @@ -1115,7 +1117,7 @@ describe('Private Execution test suite', () => { describe('Historical header in private context', () => { let artifact: FunctionArtifact; - beforeAll(() => { + beforeEach(() => { artifact = getFunctionArtifact(TestContractArtifact, 'assert_header_private'); oracle.getFunctionArtifact.mockImplementation(() => Promise.resolve(artifact)); @@ -1125,17 +1127,17 @@ describe('Private Execution test suite', () => { oracle.getHeader.mockResolvedValue(header); }); - it('Header is correctly set', () => { + it('Header is correctly set', async () => { const args = [header.hash()]; - expect(() => runSimulator({ artifact, msgSender: owner, args })).not.toThrow(); + await runSimulator({ artifact, msgSender: owner, args }); }); it('Throws when header is not as expected', async () => { const unexpectedHeaderHash = Fr.random(); const args = [unexpectedHeaderHash]; - await expect(runSimulator({ artifact, msgSender: owner, args })).rejects.toThrow('Invalid header hash'); + await expect(() => runSimulator({ artifact, msgSender: owner, args })).rejects.toThrow('Invalid header hash'); }); }); }); diff --git a/yarn-project/simulator/src/client/private_execution.ts b/yarn-project/simulator/src/client/private_execution.ts index 7a7b0d13288c..64cf9baae7d8 100644 --- a/yarn-project/simulator/src/client/private_execution.ts +++ b/yarn-project/simulator/src/client/private_execution.ts @@ -1,5 +1,5 @@ import { type FunctionData, PrivateCallStackItem, PrivateCircuitPublicInputs } from '@aztec/circuits.js'; -import { type AbiType, type FunctionArtifactWithDebugMetadata, decodeReturnValues } from '@aztec/foundation/abi'; +import { type FunctionArtifactWithDebugMetadata } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -46,19 +46,12 @@ export async function executePrivateFunction( const encryptedLogs = context.getEncryptedLogs(); const unencryptedLogs = context.getUnencryptedLogs(); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) --> set this in Noir - publicInputs.encryptedLogsHash = Fr.fromBuffer(encryptedLogs.hash()); publicInputs.encryptedLogPreimagesLength = new Fr(encryptedLogs.getSerializedLength()); - publicInputs.unencryptedLogsHash = Fr.fromBuffer(unencryptedLogs.hash()); publicInputs.unencryptedLogPreimagesLength = new Fr(unencryptedLogs.getSerializedLength()); const callStackItem = new PrivateCallStackItem(contractAddress, functionData, publicInputs); - // Mocking the return type to be an array of 4 fields - // TODO: @LHerskind must be updated as we are progressing with the macros to get the information const rawReturnValues = await context.unpackReturns(publicInputs.returnsHash); - const returnTypes: AbiType[] = [{ kind: 'array', length: rawReturnValues.length, type: { kind: 'field' } }]; - const mockArtifact = { ...artifact, returnTypes }; - const returnValues = decodeReturnValues(mockArtifact, rawReturnValues); const noteHashReadRequestPartialWitnesses = context.getNoteHashReadRequestPartialWitnesses( publicInputs.noteHashReadRequests, @@ -73,7 +66,7 @@ export async function executePrivateFunction( acir, partialWitness, callStackItem, - returnValues, + returnValues: rawReturnValues, noteHashReadRequestPartialWitnesses, newNotes, vk: Buffer.from(artifact.verificationKey!, 'hex'), diff --git a/yarn-project/simulator/src/client/simulator.ts b/yarn-project/simulator/src/client/simulator.ts index 64c963cff81f..25bd77e8688e 100644 --- a/yarn-project/simulator/src/client/simulator.ts +++ b/yarn-project/simulator/src/client/simulator.ts @@ -1,5 +1,5 @@ import { type AztecNode, type FunctionCall, type Note, type TxExecutionRequest } from '@aztec/circuit-types'; -import { CallContext, FunctionData, GasSettings } from '@aztec/circuits.js'; +import { CallContext, FunctionData } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { type ArrayType, @@ -89,16 +89,17 @@ export class AcirSimulator { // reserve the first side effect for the tx hash (inserted by the private kernel) const startSideEffectCounter = 1; - const transactionFee = Fr.ZERO; // TODO(palla/gas-in-circuits) + const transactionFee = Fr.ZERO; const callContext = new CallContext( msgSender, contractAddress, portalContractAddress, FunctionSelector.fromNameAndParameters(entryPointArtifact.name, entryPointArtifact.parameters), + request.gasSettings.getInitialAvailable(), false, false, startSideEffectCounter, - GasSettings.empty(), // TODO(palla/gas-in-circuits) + request.gasSettings, transactionFee, ); const context = new ClientExecutionContext( diff --git a/yarn-project/simulator/src/client/view_data_oracle.ts b/yarn-project/simulator/src/client/view_data_oracle.ts index 13f0f929cb30..2a76c3464745 100644 --- a/yarn-project/simulator/src/client/view_data_oracle.ts +++ b/yarn-project/simulator/src/client/view_data_oracle.ts @@ -38,7 +38,7 @@ export class ViewDataOracle extends TypedOracle { * Return the nullifier key pair of an account to use in a specific contract. * @param account - The account address of the nullifier key. */ - public getNullifierKeyPair(account: AztecAddress) { + public override getNullifierKeyPair(account: AztecAddress) { return this.db.getNullifierKeyPair(account, this.contractAddress); } @@ -49,7 +49,7 @@ export class ViewDataOracle extends TypedOracle { * @param leafValue - The leaf value * @returns The index and sibling path concatenated [index, sibling_path] */ - public async getMembershipWitness(blockNumber: number, treeId: MerkleTreeId, leafValue: Fr): Promise { + public override async getMembershipWitness(blockNumber: number, treeId: MerkleTreeId, leafValue: Fr): Promise { const index = await this.db.findLeafIndex(blockNumber, treeId, leafValue); if (!index) { throw new Error(`Leaf value: ${leafValue} not found in ${MerkleTreeId[treeId]}`); @@ -65,7 +65,7 @@ export class ViewDataOracle extends TypedOracle { * @param leafIndex - Index of the leaf to get sibling path for * @returns The sibling path. */ - public getSiblingPath(blockNumber: number, treeId: MerkleTreeId, leafIndex: Fr): Promise { + public override getSiblingPath(blockNumber: number, treeId: MerkleTreeId, leafIndex: Fr): Promise { return this.db.getSiblingPath(blockNumber, treeId, leafIndex.toBigInt()); } @@ -75,7 +75,7 @@ export class ViewDataOracle extends TypedOracle { * @param nullifier - Nullifier we try to find witness for. * @returns The nullifier membership witness (if found). */ - public async getNullifierMembershipWitness( + public override async getNullifierMembershipWitness( blockNumber: number, nullifier: Fr, ): Promise { @@ -91,7 +91,7 @@ export class ViewDataOracle extends TypedOracle { * list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier * we are trying to prove non-inclusion for. */ - public async getLowNullifierMembershipWitness( + public override async getLowNullifierMembershipWitness( blockNumber: number, nullifier: Fr, ): Promise { @@ -104,7 +104,10 @@ export class ViewDataOracle extends TypedOracle { * @param leafSlot - The slot of the public data tree to get the witness for. * @returns - The witness */ - public async getPublicDataTreeWitness(blockNumber: number, leafSlot: Fr): Promise { + public override async getPublicDataTreeWitness( + blockNumber: number, + leafSlot: Fr, + ): Promise { return await this.db.getPublicDataTreeWitness(blockNumber, leafSlot); } @@ -113,7 +116,7 @@ export class ViewDataOracle extends TypedOracle { * @param blockNumber - The number of a block of which to get the block header. * @returns Block extracted from a block with block number `blockNumber`. */ - public async getHeader(blockNumber: number): Promise
{ + public override async getHeader(blockNumber: number): Promise
{ const block = await this.db.getBlock(blockNumber); if (!block) { return undefined; @@ -126,7 +129,7 @@ export class ViewDataOracle extends TypedOracle { * @param address - Address to fetch the complete address for. * @returns A complete address associated with the input address. */ - public getCompleteAddress(address: AztecAddress): Promise { + public override getCompleteAddress(address: AztecAddress): Promise { return this.db.getCompleteAddress(address); } @@ -135,7 +138,7 @@ export class ViewDataOracle extends TypedOracle { * @param address - Address. * @returns A contract instance. */ - public getContractInstance(address: AztecAddress): Promise { + public override getContractInstance(address: AztecAddress): Promise { return this.db.getContractInstance(address); } @@ -145,7 +148,7 @@ export class ViewDataOracle extends TypedOracle { * @param messageHash - Hash of the message to authenticate. * @returns Authentication witness for the requested message hash. */ - public getAuthWitness(messageHash: Fr): Promise { + public override getAuthWitness(messageHash: Fr): Promise { return Promise.resolve( this.authWitnesses.find(w => w.requestHash.equals(messageHash))?.witness ?? this.db.getAuthWitness(messageHash), ); @@ -156,7 +159,7 @@ export class ViewDataOracle extends TypedOracle { * @returns The capsule values * @remarks A capsule is a "blob" of data that is passed to the contract through an oracle. */ - public popCapsule(): Promise { + public override popCapsule(): Promise { return this.db.popCapsule(); } @@ -181,7 +184,7 @@ export class ViewDataOracle extends TypedOracle { * @param status - The status of notes to fetch. * @returns Array of note data. */ - public async getNotes( + public override async getNotes( storageSlot: Fr, numSelects: number, selectByIndexes: number[], @@ -218,7 +221,7 @@ export class ViewDataOracle extends TypedOracle { * @param innerNullifier - The inner nullifier. * @returns A boolean indicating whether the nullifier exists in the tree or not. */ - public async checkNullifierExists(innerNullifier: Fr) { + public override async checkNullifierExists(innerNullifier: Fr) { const nullifier = siloNullifier(this.contractAddress, innerNullifier!); const index = await this.db.getNullifierIndex(nullifier); return index !== undefined; @@ -232,7 +235,7 @@ export class ViewDataOracle extends TypedOracle { * @dev Contract address and secret are only used to compute the nullifier to get non-nullified messages * @returns The l1 to l2 membership witness (index of message in the tree and sibling path). */ - public async getL1ToL2MembershipWitness(contractAddress: AztecAddress, messageHash: Fr, secret: Fr) { + public override async getL1ToL2MembershipWitness(contractAddress: AztecAddress, messageHash: Fr, secret: Fr) { return await this.db.getL1ToL2MembershipWitness(contractAddress, messageHash, secret); } @@ -242,7 +245,7 @@ export class ViewDataOracle extends TypedOracle { * @param contractAddress - The address of the contract whose portal address is to be fetched. * @returns The portal contract address. */ - public getPortalContractAddress(contractAddress: AztecAddress) { + public override getPortalContractAddress(contractAddress: AztecAddress) { return this.db.getPortalContractAddress(contractAddress); } @@ -251,7 +254,7 @@ export class ViewDataOracle extends TypedOracle { * @param startStorageSlot - The starting storage slot. * @param numberOfElements - Number of elements to read from the starting storage slot. */ - public async storageRead(startStorageSlot: Fr, numberOfElements: number) { + public override async storageRead(startStorageSlot: Fr, numberOfElements: number) { const values = []; for (let i = 0n; i < numberOfElements; i++) { const storageSlot = new Fr(startStorageSlot.value + i); diff --git a/yarn-project/simulator/src/mocks/fixtures.ts b/yarn-project/simulator/src/mocks/fixtures.ts index cdcfba83666e..96d2c9cc39e9 100644 --- a/yarn-project/simulator/src/mocks/fixtures.ts +++ b/yarn-project/simulator/src/mocks/fixtures.ts @@ -8,6 +8,7 @@ import { EthAddress, Fr, FunctionData, + Gas, GasSettings, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, type PrivateKernelTailCircuitPublicInputs, @@ -71,10 +72,11 @@ export class PublicExecutionResultBuilder { tx.to, EthAddress.ZERO, tx.functionData.selector, + Gas.test(), false, false, 0, - GasSettings.empty(), + GasSettings.default(), Fr.ZERO, ), contractAddress: tx.to, @@ -125,11 +127,13 @@ export class PublicExecutionResultBuilder { newNullifiers: [], newL2ToL1Messages: [], contractStorageReads: [], + unencryptedLogsHashes: [], unencryptedLogs: UnencryptedFunctionL2Logs.empty(), startSideEffectCounter: Fr.ZERO, endSideEffectCounter: Fr.ZERO, reverted: this._reverted, revertReason: this._revertReason, + gasLeft: this._execution.callContext.gasLeft.mul(0.9), }; } } diff --git a/yarn-project/simulator/src/public/abstract_phase_manager.ts b/yarn-project/simulator/src/public/abstract_phase_manager.ts index 092adbbc6202..2f62dd004d4f 100644 --- a/yarn-project/simulator/src/public/abstract_phase_manager.ts +++ b/yarn-project/simulator/src/public/abstract_phase_manager.ts @@ -1,5 +1,6 @@ import { MerkleTreeId, + type ProcessReturnValues, type PublicKernelRequest, type SimulationError, type Tx, @@ -11,6 +12,7 @@ import { ContractStorageRead, ContractStorageUpdateRequest, Fr, + Gas, type GlobalVariables, type Header, type KernelCircuitPublicInputs, @@ -25,6 +27,7 @@ import { MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_CALL, MembershipWitness, type PrivateKernelTailCircuitPublicInputs, type Proof, @@ -46,13 +49,6 @@ import { makeEmptyProof, } from '@aztec/circuits.js'; import { computeVarArgsHash } from '@aztec/circuits.js/hash'; -import { - type AbiType, - type DecodedReturn, - type FunctionArtifact, - type ProcessReturnValues, - decodeReturnValues, -} from '@aztec/foundation/abi'; import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { type Tuple } from '@aztec/foundation/serialize'; @@ -235,13 +231,11 @@ export abstract class AbstractPhaseManager { // separate public callstacks to be proven by separate public kernel sequences // and submitted separately to the base rollup? - const returns = []; + let returns: ProcessReturnValues = undefined; for (const enqueuedCall of enqueuedCalls) { const executionStack: (PublicExecution | PublicExecutionResult)[] = [enqueuedCall]; - let currentReturn: DecodedReturn | undefined = undefined; - // Keep track of which result is for the top/enqueued call let enqueuedExecutionResult: PublicExecutionResult | undefined; @@ -300,21 +294,12 @@ export abstract class AbstractPhaseManager { if (!enqueuedExecutionResult) { enqueuedExecutionResult = result; - - // TODO(#5450) Need to use the proper return values here - const returnTypes: AbiType[] = [ - { kind: 'array', length: result.returnValues.length, type: { kind: 'field' } }, - ]; - const mockArtifact = { returnTypes } as any as FunctionArtifact; - - currentReturn = decodeReturnValues(mockArtifact, result.returnValues); + returns = result.returnValues; } } // HACK(#1622): Manually patches the ordering of public state actions // TODO(#757): Enforce proper ordering of public state actions patchPublicStorageActionOrdering(kernelOutput, enqueuedExecutionResult!, this.phase); - - returns.push(currentReturn); } // TODO(#3675): This should be done in a public kernel circuit @@ -338,14 +323,15 @@ export abstract class AbstractPhaseManager { ): Promise<[PublicKernelCircuitPrivateInputs, PublicKernelCircuitPublicInputs]> { const previousKernel = this.getPreviousKernelData(previousOutput, previousProof); + // We take a deep copy (clone) of these inputs to be passed to the prover const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData); switch (this.phase) { case PublicKernelPhase.SETUP: - return [inputs, await this.publicKernel.publicKernelCircuitSetup(inputs)]; + return [inputs.clone(), await this.publicKernel.publicKernelCircuitSetup(inputs)]; case PublicKernelPhase.APP_LOGIC: - return [inputs, await this.publicKernel.publicKernelCircuitAppLogic(inputs)]; + return [inputs.clone(), await this.publicKernel.publicKernelCircuitAppLogic(inputs)]; case PublicKernelPhase.TEARDOWN: - return [inputs, await this.publicKernel.publicKernelCircuitTeardown(inputs)]; + return [inputs.clone(), await this.publicKernel.publicKernelCircuitTeardown(inputs)]; default: throw new Error(`No public kernel circuit for inputs`); } @@ -373,8 +359,6 @@ export abstract class AbstractPhaseManager { MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, ); - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) --> set this in Noir - const unencryptedLogsHash = Fr.fromBuffer(result.unencryptedLogs.hash()); const unencryptedLogPreimagesLength = new Fr(result.unencryptedLogs.getSerializedLength()); return PublicCircuitPublicInputs.from({ @@ -408,11 +392,16 @@ export abstract class AbstractPhaseManager { MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, ), publicCallStackHashes, - unencryptedLogsHash, + unencryptedLogsHashes: padArrayEnd( + result.unencryptedLogsHashes, + SideEffect.empty(), + MAX_UNENCRYPTED_LOGS_PER_CALL, + ), unencryptedLogPreimagesLength, historicalHeader: this.historicalHeader, // TODO(@just-mitch): need better mapping from simulator to revert code. revertCode: result.reverted ? RevertCode.REVERTED : RevertCode.OK, + gasLeft: Gas.from(result.gasLeft), }); } @@ -515,29 +504,9 @@ function patchPublicStorageActionOrdering( // so the returned result will be a subset of the public kernel output. const simPublicDataReads = collectPublicDataReads(execResult); - // verify that each read is in the kernel output - for (const read of simPublicDataReads) { - if (!publicDataReads.find(item => item.equals(read))) { - throw new Error( - `Public data reads from simulator do not match those from public kernel.\nFrom simulator: ${simPublicDataReads - .map(p => p.toFriendlyJSON()) - .join(', ')}\nFrom public kernel: ${publicDataReads.map(i => i.toFriendlyJSON()).join(', ')}`, - ); - } - } const simPublicDataUpdateRequests = collectPublicDataUpdateRequests(execResult); - for (const update of simPublicDataUpdateRequests) { - if (!publicDataUpdateRequests.find(item => item.equals(update))) { - throw new Error( - `Public data update requests from simulator do not match those from public kernel.\nFrom simulator: ${simPublicDataUpdateRequests - .map(p => p.toFriendlyJSON()) - .join(', ')}\nFrom public kernel revertible: ${publicDataUpdateRequests - .map(i => i.toFriendlyJSON()) - .join(', ')}`, - ); - } - } + // We only want to reorder the items from the public inputs of the // most recently processed top/enqueued call. diff --git a/yarn-project/simulator/src/public/app_logic_phase_manager.ts b/yarn-project/simulator/src/public/app_logic_phase_manager.ts index b3253260b837..d55c439a83c7 100644 --- a/yarn-project/simulator/src/public/app_logic_phase_manager.ts +++ b/yarn-project/simulator/src/public/app_logic_phase_manager.ts @@ -17,14 +17,14 @@ import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simul */ export class AppLogicPhaseManager extends AbstractPhaseManager { constructor( - protected db: MerkleTreeOperations, - protected publicExecutor: PublicExecutor, - protected publicKernel: PublicKernelCircuitSimulator, - protected globalVariables: GlobalVariables, - protected historicalHeader: Header, + db: MerkleTreeOperations, + publicExecutor: PublicExecutor, + publicKernel: PublicKernelCircuitSimulator, + globalVariables: GlobalVariables, + historicalHeader: Header, protected publicContractsDB: ContractsDataSourcePublicDB, protected publicStateDB: PublicStateDB, - public phase: PublicKernelPhase = PublicKernelPhase.APP_LOGIC, + phase: PublicKernelPhase = PublicKernelPhase.APP_LOGIC, ) { super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase); } diff --git a/yarn-project/simulator/src/public/avm_executor.test.ts b/yarn-project/simulator/src/public/avm_executor.test.ts index ef274232afd9..43c1dc7663c3 100644 --- a/yarn-project/simulator/src/public/avm_executor.test.ts +++ b/yarn-project/simulator/src/public/avm_executor.test.ts @@ -4,6 +4,7 @@ import { EthAddress, FunctionData, FunctionSelector, + Gas, GasSettings, type Header, } from '@aztec/circuits.js'; @@ -30,6 +31,7 @@ describe('AVM WitGen and Proof Generation', () => { storageContractAddress: AztecAddress.random(), portalContractAddress: EthAddress.random(), functionSelector: FunctionSelector.empty(), + gasLeft: Gas.test(), isDelegateCall: false, isStaticCall: false, sideEffectCounter: 0, @@ -70,6 +72,6 @@ describe('AVM WitGen and Proof Generation', () => { const valid = await executor.verifyAvmProof(vk, proof); expect(valid).toBe(true); }, - 60 * 1000, - ); // 60 seconds should be enough to generate the proof with 16-bit range checks + 120 * 1000, + ); // 120 seconds should be enough to generate the proof with 16-bit range checks }); diff --git a/yarn-project/simulator/src/public/db.ts b/yarn-project/simulator/src/public/db.ts index 88d2a66025a9..68e08315d6b7 100644 --- a/yarn-project/simulator/src/public/db.ts +++ b/yarn-project/simulator/src/public/db.ts @@ -92,6 +92,12 @@ export interface CommitmentsDB { secret: Fr, ): Promise>; + /** + * @param leafIndex the leaf to look up + * @returns The l1 to l2 leaf value or undefined if not found. + */ + getL1ToL2LeafValue(leafIndex: bigint): Promise; + /** * Gets the index of a commitment in the note hash tree. * @param commitment - The commitment. diff --git a/yarn-project/simulator/src/public/execution.ts b/yarn-project/simulator/src/public/execution.ts index 96ac9e84e97c..8b16f6c8e49e 100644 --- a/yarn-project/simulator/src/public/execution.ts +++ b/yarn-project/simulator/src/public/execution.ts @@ -1,6 +1,5 @@ import { type SimulationError, type UnencryptedFunctionL2Logs } from '@aztec/circuit-types'; import { - type AztecAddress, type ContractStorageRead, type ContractStorageUpdateRequest, type Fr, @@ -14,6 +13,8 @@ import { } from '@aztec/circuits.js'; import { computePublicDataTreeLeafSlot, computePublicDataTreeValue } from '@aztec/circuits.js/hash'; +import { type Gas } from '../avm/avm_gas.js'; + /** * The public function execution result. */ @@ -42,9 +43,14 @@ export interface PublicExecutionResult { contractStorageUpdateRequests: ContractStorageUpdateRequest[]; /** The results of nested calls. */ nestedExecutions: this[]; + /** + * The hashed logs with side effect counter. + * Note: required as we don't track the counter anywhere else. + */ + unencryptedLogsHashes: SideEffect[]; /** * Unencrypted logs emitted during execution of this function call. - * Note: These are preimages to `unencryptedLogsHash`. + * Note: These are preimages to `unencryptedLogsHashes`. */ unencryptedLogs: UnencryptedFunctionL2Logs; /** @@ -55,6 +61,8 @@ export interface PublicExecutionResult { * The revert reason if the execution reverted. */ revertReason: SimulationError | undefined; + /** How much gas was left after this public execution. */ + gasLeft: Gas; } /** @@ -81,10 +89,8 @@ export function isPublicExecutionResult( */ export function collectPublicDataReads(execResult: PublicExecutionResult): PublicDataRead[] { // HACK(#1622): part of temporary hack - may be able to remove this function after public state ordering is fixed - const contractAddress = execResult.execution.callContext.storageContractAddress; - const thisExecPublicDataReads = execResult.contractStorageReads.map(read => - contractStorageReadToPublicDataRead(read, contractAddress), + contractStorageReadToPublicDataRead(read), ); const unsorted = [ ...thisExecPublicDataReads, @@ -101,10 +107,8 @@ export function collectPublicDataReads(execResult: PublicExecutionResult): Publi */ export function collectPublicDataUpdateRequests(execResult: PublicExecutionResult): PublicDataUpdateRequest[] { // HACK(#1622): part of temporary hack - may be able to remove this function after public state ordering is fixed - const contractAddress = execResult.execution.callContext.storageContractAddress; - const thisExecPublicDataUpdateRequests = execResult.contractStorageUpdateRequests.map(update => - contractStorageUpdateRequestToPublicDataUpdateRequest(update, contractAddress), + contractStorageUpdateRequestToPublicDataUpdateRequest(update), ); const unsorted = [ ...thisExecPublicDataUpdateRequests, @@ -119,9 +123,9 @@ export function collectPublicDataUpdateRequests(execResult: PublicExecutionResul * @param contractAddress - the contract address of the read * @returns The public data read. */ -function contractStorageReadToPublicDataRead(read: ContractStorageRead, contractAddress: AztecAddress): PublicDataRead { +function contractStorageReadToPublicDataRead(read: ContractStorageRead): PublicDataRead { return new PublicDataRead( - computePublicDataTreeLeafSlot(contractAddress, read.storageSlot), + computePublicDataTreeLeafSlot(read.contractAddress!, read.storageSlot), computePublicDataTreeValue(read.currentValue), read.sideEffectCounter!, ); @@ -135,10 +139,9 @@ function contractStorageReadToPublicDataRead(read: ContractStorageRead, contract */ function contractStorageUpdateRequestToPublicDataUpdateRequest( update: ContractStorageUpdateRequest, - contractAddress: AztecAddress, ): PublicDataUpdateRequest { return new PublicDataUpdateRequest( - computePublicDataTreeLeafSlot(contractAddress, update.storageSlot), + computePublicDataTreeLeafSlot(update.contractAddress!, update.storageSlot), computePublicDataTreeValue(update.newValue), update.sideEffectCounter!, ); diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index c805b4496a86..412ea1b973b8 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -1,5 +1,5 @@ import { UnencryptedFunctionL2Logs } from '@aztec/circuit-types'; -import { Fr, type GlobalVariables, type Header, PublicCircuitPublicInputs } from '@aztec/circuits.js'; +import { Fr, Gas, type GlobalVariables, type Header, PublicCircuitPublicInputs } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { spawn } from 'child_process'; @@ -66,9 +66,7 @@ async function executePublicFunctionAvm(executionContext: PublicExecutionContext executionContext.globalVariables, ); - // TODO(@spalladino) Load initial gas from the public execution request - const machineState = new AvmMachineState(1e7, 1e7, 1e7); - + const machineState = new AvmMachineState(executionContext.execution.callContext.gasLeft); const context = new AvmContext(worldStateJournal, executionEnv, machineState); const simulator = new AvmSimulator(context); @@ -79,8 +77,7 @@ async function executePublicFunctionAvm(executionContext: PublicExecutionContext `[AVM] ${address.toString()}:${selector} returned, reverted: ${result.reverted}, reason: ${result.revertReason}.`, ); - // TODO(@spalladino) Read gas left from machineState and return it - return await convertAvmResults(executionContext, newWorldState, result); + return await convertAvmResults(executionContext, newWorldState, result, machineState); } async function executePublicFunctionAcvm( @@ -151,9 +148,11 @@ async function executePublicFunctionAcvm( contractStorageReads: [], contractStorageUpdateRequests: [], nestedExecutions: [], + unencryptedLogsHashes: [], unencryptedLogs: UnencryptedFunctionL2Logs.empty(), reverted, revertReason, + gasLeft: Gas.empty(), }; } @@ -171,6 +170,7 @@ async function executePublicFunctionAcvm( newNullifiers: newNullifiersPadded, startSideEffectCounter, endSideEffectCounter, + unencryptedLogsHashes: unencryptedLogsHashesPadded, } = PublicCircuitPublicInputs.fromFields(returnWitness); const returnValues = await context.unpackReturns(returnsHash); @@ -179,6 +179,7 @@ async function executePublicFunctionAcvm( const newL2ToL1Messages = newL2ToL1Msgs.filter(v => !v.isEmpty()); const newNoteHashes = newNoteHashesPadded.filter(v => !v.isEmpty()); const newNullifiers = newNullifiersPadded.filter(v => !v.isEmpty()); + const unencryptedLogsHashes = unencryptedLogsHashesPadded.filter(v => !v.isEmpty()); const { contractStorageReads, contractStorageUpdateRequests } = context.getStorageActionData(); @@ -195,6 +196,7 @@ async function executePublicFunctionAcvm( const nestedExecutions = context.getNestedExecutions(); const unencryptedLogs = context.getUnencryptedLogs(); + const gasLeft = context.execution.callContext.gasLeft; // No gas metering for ACVM return { execution, @@ -209,9 +211,11 @@ async function executePublicFunctionAcvm( contractStorageUpdateRequests, returnValues, nestedExecutions, + unencryptedLogsHashes, unencryptedLogs, reverted: false, revertReason: undefined, + gasLeft, }; } diff --git a/yarn-project/simulator/src/public/hints_builder.ts b/yarn-project/simulator/src/public/hints_builder.ts index b2a581d76962..5cc4988fd6fe 100644 --- a/yarn-project/simulator/src/public/hints_builder.ts +++ b/yarn-project/simulator/src/public/hints_builder.ts @@ -1,65 +1,77 @@ import { MerkleTreeId } from '@aztec/circuit-types'; import { type Fr, - MAX_NEW_NULLIFIERS_PER_TX, + type MAX_NEW_NULLIFIERS_PER_TX, type MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, type MAX_NULLIFIER_READ_REQUESTS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX, + type MAX_PUBLIC_DATA_HINTS, + type MAX_PUBLIC_DATA_READS_PER_TX, + type MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MembershipWitness, NULLIFIER_TREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, + type PublicDataHint, type PublicDataRead, - PublicDataTreeLeafPreimage, + type PublicDataTreeLeafPreimage, + type PublicDataUpdateRequest, type ReadRequestContext, type SideEffectLinkedToNoteHash, buildNullifierNonExistentReadRequestHints, buildNullifierReadRequestHints, - mergeAccumulatedData, + buildPublicDataHints, + buildPublicDataReadRequestHints, } from '@aztec/circuits.js'; -import { makeTuple } from '@aztec/foundation/array'; import { type Tuple } from '@aztec/foundation/serialize'; -import { type MerkleTreeOperations } from '@aztec/world-state'; +import { type IndexedTreeId, type MerkleTreeOperations } from '@aztec/world-state'; export class HintsBuilder { constructor(private db: MerkleTreeOperations) {} getNullifierReadRequestHints( nullifierReadRequests: Tuple, - nullifiersNonRevertible: Tuple, - nullifiersRevertible: Tuple, + pendingNullifiers: Tuple, ) { - return buildNullifierReadRequestHints( - this, - nullifierReadRequests, - mergeAccumulatedData(MAX_NEW_NULLIFIERS_PER_TX, nullifiersNonRevertible, nullifiersRevertible), - ); + return buildNullifierReadRequestHints(this, nullifierReadRequests, pendingNullifiers); } getNullifierNonExistentReadRequestHints( nullifierNonExistentReadRequests: Tuple, - nullifiersNonRevertible: Tuple, - nullifiersRevertible: Tuple, + pendingNullifiers: Tuple, ) { - const pendingNullifiers = mergeAccumulatedData( - MAX_NEW_NULLIFIERS_PER_TX, - nullifiersNonRevertible, - nullifiersRevertible, - ); return buildNullifierNonExistentReadRequestHints(this, nullifierNonExistentReadRequests, pendingNullifiers); } + getPublicDataHints( + publicDataReads: Tuple, + publicDataUpdateRequests: Tuple, + ) { + return buildPublicDataHints(this, publicDataReads, publicDataUpdateRequests); + } + + getPublicDataReadRequestHints( + publicDataReads: Tuple, + publicDataUpdateRequests: Tuple, + publicDataHints: Tuple, + ) { + return buildPublicDataReadRequestHints(publicDataReads, publicDataUpdateRequests, publicDataHints); + } + async getNullifierMembershipWitness(nullifier: Fr) { const index = await this.db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer()); if (index === undefined) { - return; + throw new Error(`Cannot find the leaf for nullifier ${nullifier.toBigInt()}.`); } - return this.getNullifierMembershipWitnessWithPreimage(index); + return this.getMembershipWitnessWithPreimage( + MerkleTreeId.NULLIFIER_TREE, + NULLIFIER_TREE_HEIGHT, + index, + ); } async getLowNullifierMembershipWitness(nullifier: Fr) { const res = await this.db.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt()); - if (res === undefined) { + if (!res) { throw new Error(`Cannot find the low leaf for nullifier ${nullifier.toBigInt()}.`); } @@ -68,52 +80,40 @@ export class HintsBuilder { throw new Error(`Nullifier ${nullifier.toBigInt()} already exists in the tree.`); } - return this.getNullifierMembershipWitnessWithPreimage(index); - } - - private async getNullifierMembershipWitnessWithPreimage(index: bigint) { - const siblingPath = await this.db.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, index); - const membershipWitness = new MembershipWitness( + return this.getMembershipWitnessWithPreimage( + MerkleTreeId.NULLIFIER_TREE, NULLIFIER_TREE_HEIGHT, index, - siblingPath.toTuple(), ); + } - const leafPreimage = await this.db.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, index); - if (!leafPreimage) { - throw new Error(`Cannot find the leaf preimage at index ${index}.`); + async getMatchOrLowPublicDataMembershipWitness(leafSlot: bigint) { + const res = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot); + if (!res) { + throw new Error(`Cannot find the previous value index for public data ${leafSlot}.`); } - return { membershipWitness, leafPreimage }; + const { membershipWitness, leafPreimage } = await this.getMembershipWitnessWithPreimage< + typeof PUBLIC_DATA_TREE_HEIGHT + >(MerkleTreeId.PUBLIC_DATA_TREE, PUBLIC_DATA_TREE_HEIGHT, res.index); + + // Should find a way to stop casting IndexedTreeLeafPreimage as PublicDataTreeLeafPreimage everywhere. + return { membershipWitness, leafPreimage: leafPreimage as PublicDataTreeLeafPreimage }; } - async getPublicDataReadsInfo(publicDataReads: PublicDataRead[]) { - const newPublicDataReadsWitnesses: Tuple< - MembershipWitness, - typeof MAX_PUBLIC_DATA_READS_PER_TX - > = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT, 0n)); - - const newPublicDataReadsPreimages: Tuple = - makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataTreeLeafPreimage.empty()); - - for (const i in publicDataReads) { - const leafSlot = publicDataReads[i].leafSlot.value; - const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot); - if (!lowLeafResult) { - throw new Error(`Public data tree should have one initial leaf`); - } - const preimage = await this.db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index); - const path = await this.db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index); - newPublicDataReadsWitnesses[i] = new MembershipWitness( - PUBLIC_DATA_TREE_HEIGHT, - BigInt(lowLeafResult.index), - path.toTuple(), - ); - newPublicDataReadsPreimages[i] = preimage! as PublicDataTreeLeafPreimage; + private async getMembershipWitnessWithPreimage( + treeId: IndexedTreeId, + treeHeight: TREE_HEIGHT, + index: bigint, + ) { + const siblingPath = await this.db.getSiblingPath(treeId, index); + const membershipWitness = new MembershipWitness(treeHeight, index, siblingPath.toTuple()); + + const leafPreimage = await this.db.getLeafPreimage(treeId, index); + if (!leafPreimage) { + throw new Error(`Cannot find the leaf preimage for tree ${treeId} at index ${index}.`); } - return { - newPublicDataReadsWitnesses, - newPublicDataReadsPreimages, - }; + + return { membershipWitness, leafPreimage }; } } diff --git a/yarn-project/simulator/src/public/index.test.ts b/yarn-project/simulator/src/public/index.test.ts index d309a73f5e67..6f74908fadde 100644 --- a/yarn-project/simulator/src/public/index.test.ts +++ b/yarn-project/simulator/src/public/index.test.ts @@ -3,6 +3,7 @@ import { AppendOnlyTreeSnapshot, CallContext, FunctionData, + Gas, GasFees, GasSettings, GlobalVariables, @@ -47,6 +48,9 @@ describe('ACIR public execution simulator', () => { let executor: PublicExecutor; let header: Header; + const gasLeft = new Gas(1e9, 1e9, 1e9); + const globalVariables = GlobalVariables.empty(); + beforeEach(() => { publicState = mock(); publicContracts = mock(); @@ -89,6 +93,7 @@ describe('ACIR public execution simulator', () => { CallContext.from({ storageContractAddress, msgSender: AztecAddress.random(), + gasLeft, portalContractAddress: EthAddress.random(), functionSelector: FunctionSelector.empty(), isDelegateCall: false, @@ -132,7 +137,8 @@ describe('ACIR public execution simulator', () => { .mockResolvedValueOnce(previousTotalSupply); // reading total supply const execution: PublicExecution = { contractAddress, functionData, args, callContext }; - const result = await executor.simulate(execution, GlobalVariables.empty()); + const result = await executor.simulate(execution, globalVariables); + expect(result.revertReason).toBeUndefined(); const recipientBalanceStorageSlot = computeSlotForMapping(new Fr(6n), recipient); const totalSupplyStorageSlot = new Fr(4n); @@ -142,11 +148,13 @@ describe('ACIR public execution simulator', () => { // There should be 2 storage updates, one for the recipient's balance and one for the total supply expect(result.contractStorageUpdateRequests).toEqual([ { + contractAddress, storageSlot: recipientBalanceStorageSlot, newValue: expectedBalance, sideEffectCounter: 3, }, { + contractAddress, storageSlot: totalSupplyStorageSlot, newValue: expectedTotalSupply, sideEffectCounter: 4, @@ -159,6 +167,7 @@ describe('ACIR public execution simulator', () => { // the updates expect(result.contractStorageReads).toEqual([ { + contractAddress, storageSlot: isMinterStorageSlot, currentValue: isMinter, sideEffectCounter: 0, @@ -210,18 +219,20 @@ describe('ACIR public execution simulator', () => { const recipientBalance = new Fr(20n); mockStore(senderBalance, recipientBalance); - const result = await executor.simulate(execution, GlobalVariables.empty()); + const result = await executor.simulate(execution, globalVariables); const expectedRecipientBalance = new Fr(160n); const expectedSenderBalance = new Fr(60n); expect(result.contractStorageUpdateRequests).toEqual([ { + contractAddress, storageSlot: senderStorageSlot, newValue: expectedSenderBalance, sideEffectCounter: 1, // 1 read (sender balance) }, { + contractAddress, storageSlot: recipientStorageSlot, newValue: expectedRecipientBalance, sideEffectCounter: 3, // 1 read (sender balance), 1 write (new sender balance), 1 read (recipient balance) @@ -236,7 +247,7 @@ describe('ACIR public execution simulator', () => { const recipientBalance = new Fr(20n); mockStore(senderBalance, recipientBalance); - const { reverted, revertReason } = await executor.simulate(execution, GlobalVariables.empty()); + const { reverted, revertReason } = await executor.simulate(execution, globalVariables); expect(reverted).toBe(true); expect(revertReason?.message).toMatch('Assertion failed: attempt to subtract with underflow'); }); @@ -325,7 +336,7 @@ describe('ACIR public execution simulator', () => { publicState.storageRead.mockResolvedValue(amount); const execution: PublicExecution = { contractAddress, functionData, args, callContext }; - const result = await executor.simulate(execution, GlobalVariables.empty()); + const result = await executor.simulate(execution, globalVariables); // Assert the note hash was created expect(result.newNoteHashes.length).toEqual(1); @@ -349,7 +360,7 @@ describe('ACIR public execution simulator', () => { publicContracts.getBytecode.mockResolvedValue(createL2ToL1MessagePublicArtifact.bytecode); const execution: PublicExecution = { contractAddress, functionData, args, callContext }; - const result = await executor.simulate(execution, GlobalVariables.empty()); + const result = await executor.simulate(execution, globalVariables); // Assert the l2 to l1 message was created expect(result.newL2ToL1Messages.length).toEqual(1); @@ -371,7 +382,7 @@ describe('ACIR public execution simulator', () => { publicContracts.getBytecode.mockResolvedValue(createNullifierPublicArtifact.bytecode); const execution: PublicExecution = { contractAddress, functionData, args, callContext }; - const result = await executor.simulate(execution, GlobalVariables.empty()); + const result = await executor.simulate(execution, globalVariables); // Assert the l2 to l1 message was created expect(result.newNullifiers.length).toEqual(1); @@ -386,6 +397,7 @@ describe('ACIR public execution simulator', () => { const tokenRecipient = AztecAddress.random(); let bridgedAmount = 20n; let secret = new Fr(1); + let leafIndex: bigint; let crossChainMsgRecipient: AztecAddress | undefined; let crossChainMsgSender: EthAddress | undefined; @@ -399,6 +411,7 @@ describe('ACIR public execution simulator', () => { beforeEach(() => { bridgedAmount = 20n; secret = new Fr(1); + leafIndex = 0n; crossChainMsgRecipient = undefined; crossChainMsgSender = undefined; @@ -412,7 +425,7 @@ describe('ACIR public execution simulator', () => { secret, ); - const computeArgs = () => encodeArguments(mintPublicArtifact, [tokenRecipient, bridgedAmount, secret]); + const computeArgs = () => encodeArguments(mintPublicArtifact, [tokenRecipient, bridgedAmount, secret, leafIndex]); const computeCallContext = () => makeCallContext(contractAddress, { @@ -444,7 +457,7 @@ describe('ACIR public execution simulator', () => { root = pedersenHash([root, sibling]); } commitmentsDb.getL1ToL2MembershipWitness.mockImplementation(() => { - return Promise.resolve(new MessageLoadOracleInputs(0n, siblingPath)); + return Promise.resolve(new MessageLoadOracleInputs(leafIndex, siblingPath)); }); if (updateState) { @@ -702,7 +715,7 @@ describe('ACIR public execution simulator', () => { const execution: PublicExecution = { contractAddress, functionData, args, callContext }; executor = new PublicExecutor(publicState, publicContracts, commitmentsDb, header); - expect(() => executor.simulate(execution, GlobalVariables.empty())).not.toThrow(); + expect(() => executor.simulate(execution, globalVariables)).not.toThrow(); }); it('Throws when header is not as expected', async () => { @@ -712,7 +725,7 @@ describe('ACIR public execution simulator', () => { const execution: PublicExecution = { contractAddress, functionData, args, callContext }; executor = new PublicExecutor(publicState, publicContracts, commitmentsDb, header); - const { revertReason, reverted } = await executor.simulate(execution, GlobalVariables.empty()); + const { revertReason, reverted } = await executor.simulate(execution, globalVariables); expect(reverted).toBe(true); expect(revertReason?.message).toMatch(`Invalid header hash`); }); diff --git a/yarn-project/simulator/src/public/public_execution_context.ts b/yarn-project/simulator/src/public/public_execution_context.ts index 20e41a12db6a..ad2c77b0dc92 100644 --- a/yarn-project/simulator/src/public/public_execution_context.ts +++ b/yarn-project/simulator/src/public/public_execution_context.ts @@ -3,7 +3,6 @@ import { CallContext, FunctionData, type FunctionSelector, - GasSettings, type GlobalVariables, type Header, } from '@aztec/circuits.js'; @@ -91,10 +90,10 @@ export class PublicExecutionContext extends TypedOracle { } /** - * Pack the given arguments. + * Pack the given array of arguments. * @param args - Arguments to pack */ - public packArguments(args: Fr[]): Promise { + public override packArgumentsArray(args: Fr[]): Promise { return Promise.resolve(this.packedValuesCache.pack(args)); } @@ -102,7 +101,7 @@ export class PublicExecutionContext extends TypedOracle { * Pack the given returns. * @param returns - Returns to pack */ - public packReturns(returns: Fr[]): Promise { + public override packReturns(returns: Fr[]): Promise { return Promise.resolve(this.packedValuesCache.pack(returns)); } @@ -110,7 +109,7 @@ export class PublicExecutionContext extends TypedOracle { * Unpack the given returns. * @param returnsHash - Returns hash to unpack */ - public unpackReturns(returnsHash: Fr): Promise { + public override unpackReturns(returnsHash: Fr): Promise { return Promise.resolve(this.packedValuesCache.unpack(returnsHash)); } @@ -122,7 +121,7 @@ export class PublicExecutionContext extends TypedOracle { * @dev Contract address and secret are only used to compute the nullifier to get non-nullified messages * @returns The l1 to l2 membership witness (index of message in the tree and sibling path). */ - public async getL1ToL2MembershipWitness(contractAddress: AztecAddress, messageHash: Fr, secret: Fr) { + public override async getL1ToL2MembershipWitness(contractAddress: AztecAddress, messageHash: Fr, secret: Fr) { return await this.commitmentsDb.getL1ToL2MembershipWitness(contractAddress, messageHash, secret); } @@ -130,10 +129,11 @@ export class PublicExecutionContext extends TypedOracle { * Emit an unencrypted log. * @param log - The unencrypted log to be emitted. */ - public emitUnencryptedLog(log: UnencryptedL2Log) { + public override emitUnencryptedLog(log: UnencryptedL2Log) { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/885) this.unencryptedLogs.push(log); this.log.verbose(`Emitted unencrypted log: "${log.toHumanReadable()}"`); + return Fr.fromBuffer(log.hash()); } /** @@ -142,7 +142,7 @@ export class PublicExecutionContext extends TypedOracle { * @param contractAddress - The address of the contract whose portal address is to be fetched. * @returns The portal contract address. */ - public async getPortalContractAddress(contractAddress: AztecAddress) { + public override async getPortalContractAddress(contractAddress: AztecAddress) { return (await this.contractsDb.getPortalContractAddress(contractAddress)) ?? EthAddress.ZERO; } @@ -151,7 +151,7 @@ export class PublicExecutionContext extends TypedOracle { * @param startStorageSlot - The starting storage slot. * @param numberOfElements - Number of elements to read from the starting storage slot. */ - public async storageRead(startStorageSlot: Fr, numberOfElements: number) { + public override async storageRead(startStorageSlot: Fr, numberOfElements: number) { const values = []; for (let i = 0; i < Number(numberOfElements); i++) { const storageSlot = new Fr(startStorageSlot.value + BigInt(i)); @@ -168,7 +168,7 @@ export class PublicExecutionContext extends TypedOracle { * @param startStorageSlot - The starting storage slot. * @param values - The values to be written. */ - public async storageWrite(startStorageSlot: Fr, values: Fr[]) { + public override async storageWrite(startStorageSlot: Fr, values: Fr[]) { const newValues = []; for (let i = 0; i < values.length; i++) { const storageSlot = new Fr(startStorageSlot.toBigInt() + BigInt(i)); @@ -189,7 +189,7 @@ export class PublicExecutionContext extends TypedOracle { * @param argsHash - The packed arguments to pass to the function. * @returns The return values of the public function. */ - public async callPublicFunction( + public override async callPublicFunction( targetContractAddress: AztecAddress, functionSelector: FunctionSelector, argsHash: Fr, @@ -206,16 +206,18 @@ export class PublicExecutionContext extends TypedOracle { const portalAddress = (await this.contractsDb.getPortalContractAddress(targetContractAddress)) ?? EthAddress.ZERO; const functionData = new FunctionData(functionSelector, /*isPrivate=*/ false); + const { transactionFee, gasSettings, gasLeft } = this.execution.callContext; const callContext = CallContext.from({ msgSender: isDelegateCall ? this.execution.callContext.msgSender : this.execution.contractAddress, storageContractAddress: isDelegateCall ? this.execution.contractAddress : targetContractAddress, portalContractAddress: portalAddress, functionSelector, + gasLeft, // Propagate the same gas left as when we started since ACVM public functions don't have any metering isDelegateCall, isStaticCall, sideEffectCounter, - transactionFee: Fr.ZERO, // TODO(palla/gas-in-circuits) - gasSettings: GasSettings.empty(), // TODO(palla/gas-in-circuits) + gasSettings, + transactionFee, }); const nestedExecution: PublicExecution = { @@ -255,12 +257,12 @@ export class PublicExecutionContext extends TypedOracle { return childExecutionResult.returnValues; } - public async checkNullifierExists(nullifier: Fr): Promise { + public override async checkNullifierExists(nullifier: Fr): Promise { const witness = await this.commitmentsDb.getNullifierMembershipWitnessAtLatestBlock(nullifier); return !!witness; } - public async getContractInstance(address: AztecAddress): Promise { + public override async getContractInstance(address: AztecAddress): Promise { // Note to AVM implementor: The wrapper of the oracle call get_contract_instance in aztec-nr // automatically checks that the returned instance is correct, by hashing it together back // into the address. However, in the AVM, we also need to prove the negative, otherwise a malicious diff --git a/yarn-project/simulator/src/public/public_executor.ts b/yarn-project/simulator/src/public/public_executor.ts index 1f1bc28115ed..c40a815732b6 100644 --- a/yarn-project/simulator/src/public/public_executor.ts +++ b/yarn-project/simulator/src/public/public_executor.ts @@ -257,6 +257,10 @@ export class WorldStateDB implements CommitmentsDB { return new MessageLoadOracleInputs(messageIndex, siblingPath); } + public async getL1ToL2LeafValue(leafIndex: bigint): Promise { + return await this.db.getLeafValue(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex); + } + public async getCommitmentIndex(commitment: Fr): Promise { return await this.db.findLeafIndex(MerkleTreeId.NOTE_HASH_TREE, commitment); } diff --git a/yarn-project/simulator/src/public/public_processor.test.ts b/yarn-project/simulator/src/public/public_processor.test.ts index 2904b08319ee..904321e2d6c3 100644 --- a/yarn-project/simulator/src/public/public_processor.test.ts +++ b/yarn-project/simulator/src/public/public_processor.test.ts @@ -1,45 +1,39 @@ import { type BlockProver, - EncryptedTxL2Logs, type ProcessedTx, PublicDataWrite, - SiblingPath, SimulationError, - Tx, + type Tx, type TxValidator, - UnencryptedTxL2Logs, mockTx, toTxEffect, } from '@aztec/circuit-types'; import { + AppendOnlyTreeSnapshot, ContractStorageUpdateRequest, Fr, GlobalVariables, Header, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PUBLIC_DATA_TREE_HEIGHT, + PartialStateReference, type Proof, type PublicCallRequest, - PublicDataUpdateRequest, + PublicDataTreeLeafPreimage, + StateReference, makeEmptyProof, } from '@aztec/circuits.js'; import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash'; -import { - fr, - makeAztecAddress, - makePrivateKernelTailCircuitPublicInputs, - makePublicCallRequest, - makeSelector, -} from '@aztec/circuits.js/testing'; -import { makeTuple } from '@aztec/foundation/array'; -import { arrayNonEmptyLength, times } from '@aztec/foundation/collection'; +import { fr, makeAztecAddress, makePublicCallRequest, makeSelector } from '@aztec/circuits.js/testing'; +import { arrayNonEmptyLength } from '@aztec/foundation/collection'; +import { openTmpStore } from '@aztec/kv-store/utils'; +import { type AppendOnlyTree, Pedersen, StandardTree, newTree } from '@aztec/merkle-tree'; import { type PublicExecutionResult, type PublicExecutor, WASMSimulator } from '@aztec/simulator'; import { type MerkleTreeOperations, type TreeInfo } from '@aztec/world-state'; import { jest } from '@jest/globals'; import { type MockProxy, mock } from 'jest-mock-extended'; -import { PublicExecutionResultBuilder, addKernelPublicCallStack, makeFunctionCall } from '../mocks/fixtures.js'; +import { PublicExecutionResultBuilder, makeFunctionCall } from '../mocks/fixtures.js'; import { type ContractsDataSourcePublicDB, type WorldStatePublicDB } from './public_executor.js'; import { RealPublicKernelCircuitSimulator } from './public_kernel.js'; import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js'; @@ -143,17 +137,68 @@ describe('public_processor', () => { describe('with actual circuits', () => { let publicKernel: PublicKernelCircuitSimulator; + let publicDataTree: AppendOnlyTree; + + const mockTxWithPartialState = ( + { + hasLogs = false, + numberOfNonRevertiblePublicCallRequests = 0, + numberOfRevertiblePublicCallRequests = 0, + publicCallRequests = [], + }: { + hasLogs?: boolean; + numberOfNonRevertiblePublicCallRequests?: number; + numberOfRevertiblePublicCallRequests?: number; + publicCallRequests?: PublicCallRequest[]; + } = {}, + seed = 1, + ) => { + return mockTx(seed, { + hasLogs, + numberOfNonRevertiblePublicCallRequests, + numberOfRevertiblePublicCallRequests, + publicCallRequests, + }); + }; + + beforeAll(async () => { + publicDataTree = await newTree( + StandardTree, + openTmpStore(), + new Pedersen(), + 'PublicData', + Fr, + PUBLIC_DATA_TREE_HEIGHT, + 1, // Add a default low leaf for the public data hints to be proved against. + ); + }); beforeEach(() => { - const path = times(PUBLIC_DATA_TREE_HEIGHT, i => Buffer.alloc(32, i)); - db.getSiblingPath.mockResolvedValue(new SiblingPath(PUBLIC_DATA_TREE_HEIGHT, path)); + const snap = new AppendOnlyTreeSnapshot( + Fr.fromBuffer(publicDataTree.getRoot(true)), + Number(publicDataTree.getNumLeaves(true)), + ); + + const header = Header.empty(); + const stateReference = new StateReference( + header.state.l1ToL2MessageTree, + new PartialStateReference(header.state.partial.noteHashTree, header.state.partial.nullifierTree, snap), + ); + // Clone the whole state because somewhere down the line (AbstractPhaseManager) the public data root is modified in the referenced header directly :/ + header.state = StateReference.fromBuffer(stateReference.toBuffer()); + + db.getStateReference.mockResolvedValue(stateReference); + db.getSiblingPath.mockResolvedValue(publicDataTree.getSiblingPath(0n, false)); + db.getPreviousValueIndex.mockResolvedValue({ index: 0n, alreadyPresent: true }); + db.getLeafPreimage.mockResolvedValue(new PublicDataTreeLeafPreimage(new Fr(0), new Fr(0), new Fr(0), 0n)); + publicKernel = new RealPublicKernelCircuitSimulator(new WASMSimulator()); processor = new PublicProcessor( db, publicExecutor, publicKernel, GlobalVariables.empty(), - Header.empty(), + header, publicContractsDB, publicWorldStateDB, ); @@ -166,7 +211,9 @@ describe('public_processor', () => { }); it('runs a tx with enqueued public calls', async function () { - const tx = mockTx(1, { numberOfNonRevertiblePublicCallRequests: 0, numberOfRevertiblePublicCallRequests: 2 }); + const tx = mockTxWithPartialState({ + numberOfRevertiblePublicCallRequests: 2, + }); publicExecutor.simulate.mockImplementation(execution => { for (const request of tx.enqueuedPublicFunctionCalls) { @@ -181,9 +228,9 @@ describe('public_processor', () => { const [processed, failed] = await processor.process([tx], 1, prover); + expect(failed.map(f => f.error)).toEqual([]); expect(processed).toHaveLength(1); expect(processed).toEqual([expectedTxByHash(tx)]); - expect(failed).toHaveLength(0); expect(publicExecutor.simulate).toHaveBeenCalledTimes(2); expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); @@ -192,7 +239,7 @@ describe('public_processor', () => { }); it('runs a tx with an enqueued public call with nested execution', async function () { - const tx = mockTx(1, { numberOfNonRevertiblePublicCallRequests: 0, numberOfRevertiblePublicCallRequests: 1 }); + const tx = mockTxWithPartialState({ numberOfRevertiblePublicCallRequests: 1 }); const callRequest = tx.enqueuedPublicFunctionCalls[0]; const publicExecutionResult = PublicExecutionResultBuilder.fromPublicCallRequest({ @@ -223,7 +270,7 @@ describe('public_processor', () => { it('does not attempt to overfill a block', async function () { const txs = Array.from([1, 2, 3], index => - mockTx(index, { numberOfNonRevertiblePublicCallRequests: 0, numberOfRevertiblePublicCallRequests: 1 }), + mockTxWithPartialState({ numberOfRevertiblePublicCallRequests: 1 }, index), ); let txCount = 0; @@ -255,7 +302,7 @@ describe('public_processor', () => { }); it('does not send a transaction to the prover if validation fails', async function () { - const tx = mockTx(1, { numberOfNonRevertiblePublicCallRequests: 0, numberOfRevertiblePublicCallRequests: 1 }); + const tx = mockTxWithPartialState({ numberOfRevertiblePublicCallRequests: 1 }); publicExecutor.simulate.mockImplementation(execution => { for (const request of tx.enqueuedPublicFunctionCalls) { @@ -283,40 +330,21 @@ describe('public_processor', () => { it('rolls back app logic db updates on failed public execution, but persists setup/teardown', async function () { const baseContractAddressSeed = 0x200; const baseContractAddress = makeAztecAddress(baseContractAddressSeed); - const callRequests: PublicCallRequest[] = [ + const publicCallRequests: PublicCallRequest[] = [ baseContractAddressSeed, baseContractAddressSeed, baseContractAddressSeed, ].map(makePublicCallRequest); - callRequests[0].callContext.sideEffectCounter = 2; - callRequests[1].callContext.sideEffectCounter = 3; - callRequests[2].callContext.sideEffectCounter = 4; - - const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); - kernelOutput.forPublic!.endNonRevertibleData.publicDataUpdateRequests = makeTuple( - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - PublicDataUpdateRequest.empty, - ); - kernelOutput.forPublic!.end.publicDataUpdateRequests = makeTuple( - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - PublicDataUpdateRequest.empty, - ); - - addKernelPublicCallStack(kernelOutput, { - setupCalls: [callRequests[0]], - appLogicCalls: [callRequests[2]], - teardownCall: callRequests[1], + publicCallRequests[0].callContext.sideEffectCounter = 2; + publicCallRequests[1].callContext.sideEffectCounter = 3; + publicCallRequests[2].callContext.sideEffectCounter = 4; + + const tx = mockTxWithPartialState({ + numberOfNonRevertiblePublicCallRequests: 2, + numberOfRevertiblePublicCallRequests: 1, + publicCallRequests, }); - const tx = new Tx( - kernelOutput, - proof, - EncryptedTxL2Logs.empty(), - UnencryptedTxL2Logs.empty(), - // reverse because `enqueuedPublicFunctions` expects the last element to be the front of the queue - callRequests.slice().reverse(), - ); - const contractSlotA = fr(0x100); const contractSlotB = fr(0x150); const contractSlotC = fr(0x200); @@ -325,24 +353,26 @@ describe('public_processor', () => { const simulatorResults: PublicExecutionResult[] = [ // Setup PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[0], - contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotA, fr(0x101))], + request: publicCallRequests[0], + contractStorageUpdateRequests: [ + new ContractStorageUpdateRequest(contractSlotA, fr(0x101), 11, baseContractAddress), + ], }).build(), // App Logic PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[2], + request: publicCallRequests[2], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ - new ContractStorageUpdateRequest(contractSlotA, fr(0x102)), - new ContractStorageUpdateRequest(contractSlotB, fr(0x151)), + new ContractStorageUpdateRequest(contractSlotA, fr(0x102), 13, baseContractAddress), + new ContractStorageUpdateRequest(contractSlotB, fr(0x151), 14, baseContractAddress), ], }).build(), PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), revertReason: new SimulationError('Simulation Failed', []), }).build(), @@ -351,12 +381,14 @@ describe('public_processor', () => { // Teardown PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[1], + request: publicCallRequests[1], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), - contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotC, fr(0x201))], + contractStorageUpdateRequests: [ + new ContractStorageUpdateRequest(contractSlotC, fr(0x201), 12, baseContractAddress), + ], }).build(), ], }).build(), @@ -406,32 +438,21 @@ describe('public_processor', () => { it('fails a transaction that reverts in setup', async function () { const baseContractAddressSeed = 0x200; const baseContractAddress = makeAztecAddress(baseContractAddressSeed); - const callRequests: PublicCallRequest[] = [ + const publicCallRequests: PublicCallRequest[] = [ baseContractAddressSeed, baseContractAddressSeed, baseContractAddressSeed, ].map(makePublicCallRequest); - callRequests[0].callContext.sideEffectCounter = 2; - callRequests[1].callContext.sideEffectCounter = 3; - callRequests[2].callContext.sideEffectCounter = 4; - - const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); - - addKernelPublicCallStack(kernelOutput, { - setupCalls: [callRequests[0]], - appLogicCalls: [callRequests[2]], - teardownCall: callRequests[1], + publicCallRequests[0].callContext.sideEffectCounter = 2; + publicCallRequests[1].callContext.sideEffectCounter = 3; + publicCallRequests[2].callContext.sideEffectCounter = 4; + + const tx = mockTxWithPartialState({ + numberOfNonRevertiblePublicCallRequests: 2, + numberOfRevertiblePublicCallRequests: 1, + publicCallRequests, }); - const tx = new Tx( - kernelOutput, - proof, - EncryptedTxL2Logs.empty(), - UnencryptedTxL2Logs.empty(), - // reverse because `enqueuedPublicFunctions` expects the last element to be the front of the queue - callRequests.slice().reverse(), - ); - const contractSlotA = fr(0x100); const contractSlotB = fr(0x150); const contractSlotC = fr(0x200); @@ -440,19 +461,21 @@ describe('public_processor', () => { const simulatorResults: PublicExecutionResult[] = [ // Setup PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[0], - contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotA, fr(0x101))], + request: publicCallRequests[0], + contractStorageUpdateRequests: [ + new ContractStorageUpdateRequest(contractSlotA, fr(0x101), 11, baseContractAddress), + ], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ - new ContractStorageUpdateRequest(contractSlotA, fr(0x102)), - new ContractStorageUpdateRequest(contractSlotB, fr(0x151)), + new ContractStorageUpdateRequest(contractSlotA, fr(0x102), 12, baseContractAddress), + new ContractStorageUpdateRequest(contractSlotB, fr(0x151), 13, baseContractAddress), ], }).build(), PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), revertReason: new SimulationError('Simulation Failed', []), }).build(), @@ -461,17 +484,19 @@ describe('public_processor', () => { // App Logic PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[2], + request: publicCallRequests[2], }).build(), // Teardown PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[1], + request: publicCallRequests[1], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), - contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotC, fr(0x201))], + contractStorageUpdateRequests: [ + new ContractStorageUpdateRequest(contractSlotC, fr(0x201), 14, baseContractAddress), + ], }).build(), ], }).build(), @@ -511,32 +536,21 @@ describe('public_processor', () => { it('fails a transaction that reverts in teardown', async function () { const baseContractAddressSeed = 0x200; const baseContractAddress = makeAztecAddress(baseContractAddressSeed); - const callRequests: PublicCallRequest[] = [ + const publicCallRequests: PublicCallRequest[] = [ baseContractAddressSeed, baseContractAddressSeed, baseContractAddressSeed, ].map(makePublicCallRequest); - callRequests[0].callContext.sideEffectCounter = 2; - callRequests[1].callContext.sideEffectCounter = 3; - callRequests[2].callContext.sideEffectCounter = 4; - - const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); - - addKernelPublicCallStack(kernelOutput, { - setupCalls: [callRequests[0]], - appLogicCalls: [callRequests[2]], - teardownCall: callRequests[1], + publicCallRequests[0].callContext.sideEffectCounter = 2; + publicCallRequests[1].callContext.sideEffectCounter = 3; + publicCallRequests[2].callContext.sideEffectCounter = 4; + + const tx = mockTxWithPartialState({ + numberOfNonRevertiblePublicCallRequests: 2, + numberOfRevertiblePublicCallRequests: 1, + publicCallRequests, }); - const tx = new Tx( - kernelOutput, - proof, - EncryptedTxL2Logs.empty(), - UnencryptedTxL2Logs.empty(), - // reverse because `enqueuedPublicFunctions` expects the last element to be the front of the queue - callRequests.slice().reverse(), - ); - const contractSlotA = fr(0x100); const contractSlotB = fr(0x150); const contractSlotC = fr(0x200); @@ -545,15 +559,17 @@ describe('public_processor', () => { const simulatorResults: PublicExecutionResult[] = [ // Setup PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[0], - contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotA, fr(0x101))], + request: publicCallRequests[0], + contractStorageUpdateRequests: [ + new ContractStorageUpdateRequest(contractSlotA, fr(0x101), 11, baseContractAddress), + ], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ - new ContractStorageUpdateRequest(contractSlotA, fr(0x102)), - new ContractStorageUpdateRequest(contractSlotB, fr(0x151)), + new ContractStorageUpdateRequest(contractSlotA, fr(0x102), 12, baseContractAddress), + new ContractStorageUpdateRequest(contractSlotB, fr(0x151), 13, baseContractAddress), ], }).build(), ], @@ -561,22 +577,24 @@ describe('public_processor', () => { // App Logic PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[2], + request: publicCallRequests[2], }).build(), // Teardown PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[1], + request: publicCallRequests[1], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), revertReason: new SimulationError('Simulation Failed', []), }).build(), PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), - contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotC, fr(0x201))], + contractStorageUpdateRequests: [ + new ContractStorageUpdateRequest(contractSlotC, fr(0x201), 14, baseContractAddress), + ], }).build(), ], }).build(), @@ -615,42 +633,21 @@ describe('public_processor', () => { it('runs a tx with setup and teardown phases', async function () { const baseContractAddressSeed = 0x200; const baseContractAddress = makeAztecAddress(baseContractAddressSeed); - const callRequests: PublicCallRequest[] = [ + const publicCallRequests: PublicCallRequest[] = [ baseContractAddressSeed, baseContractAddressSeed, baseContractAddressSeed, ].map(makePublicCallRequest); - callRequests[0].callContext.sideEffectCounter = 2; - callRequests[1].callContext.sideEffectCounter = 3; - callRequests[2].callContext.sideEffectCounter = 4; - - const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); - kernelOutput.forPublic!.end.encryptedLogsHash = Fr.ZERO; - kernelOutput.forPublic!.end.unencryptedLogsHash = Fr.ZERO; - kernelOutput.forPublic!.endNonRevertibleData.publicDataUpdateRequests = makeTuple( - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - PublicDataUpdateRequest.empty, - ); - kernelOutput.forPublic!.end.publicDataUpdateRequests = makeTuple( - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - PublicDataUpdateRequest.empty, - ); - - addKernelPublicCallStack(kernelOutput, { - setupCalls: [callRequests[0]], - appLogicCalls: [callRequests[2]], - teardownCall: callRequests[1], + publicCallRequests[0].callContext.sideEffectCounter = 2; + publicCallRequests[1].callContext.sideEffectCounter = 3; + publicCallRequests[2].callContext.sideEffectCounter = 4; + + const tx = mockTxWithPartialState({ + numberOfNonRevertiblePublicCallRequests: 2, + numberOfRevertiblePublicCallRequests: 1, + publicCallRequests, }); - const tx = new Tx( - kernelOutput, - proof, - EncryptedTxL2Logs.empty(), - UnencryptedTxL2Logs.empty(), - // reverse because `enqueuedPublicFunctions` expects the last element to be the front of the queue - callRequests.slice().reverse(), - ); - // const baseContractAddress = makeAztecAddress(30); const contractSlotA = fr(0x100); const contractSlotB = fr(0x150); @@ -659,33 +656,35 @@ describe('public_processor', () => { let simulatorCallCount = 0; const simulatorResults: PublicExecutionResult[] = [ // Setup - PublicExecutionResultBuilder.fromPublicCallRequest({ request: callRequests[0] }).build(), + PublicExecutionResultBuilder.fromPublicCallRequest({ request: publicCallRequests[0] }).build(), // App Logic PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[2], + request: publicCallRequests[2], contractStorageUpdateRequests: [ - new ContractStorageUpdateRequest(contractSlotA, fr(0x101)), - new ContractStorageUpdateRequest(contractSlotB, fr(0x151)), + new ContractStorageUpdateRequest(contractSlotA, fr(0x101), 14, baseContractAddress), + new ContractStorageUpdateRequest(contractSlotB, fr(0x151), 15, baseContractAddress), ], }).build(), // Teardown PublicExecutionResultBuilder.fromPublicCallRequest({ - request: callRequests[1], + request: publicCallRequests[1], nestedExecutions: [ PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), contractStorageUpdateRequests: [ - new ContractStorageUpdateRequest(contractSlotA, fr(0x101)), - new ContractStorageUpdateRequest(contractSlotC, fr(0x201)), + new ContractStorageUpdateRequest(contractSlotA, fr(0x101), 11, baseContractAddress), + new ContractStorageUpdateRequest(contractSlotC, fr(0x201), 12, baseContractAddress), ], }).build(), PublicExecutionResultBuilder.fromFunctionCall({ - from: callRequests[1].contractAddress, + from: publicCallRequests[1].contractAddress, tx: makeFunctionCall(baseContractAddress, makeSelector(5)), - contractStorageUpdateRequests: [new ContractStorageUpdateRequest(contractSlotA, fr(0x102))], + contractStorageUpdateRequests: [ + new ContractStorageUpdateRequest(contractSlotA, fr(0x102), 13, baseContractAddress), + ], }).build(), ], }).build(), diff --git a/yarn-project/simulator/src/public/public_processor.ts b/yarn-project/simulator/src/public/public_processor.ts index 9354bd6d6e9a..b749c2276faf 100644 --- a/yarn-project/simulator/src/public/public_processor.ts +++ b/yarn-project/simulator/src/public/public_processor.ts @@ -1,6 +1,7 @@ import { type BlockProver, type FailedTx, + type ProcessReturnValues, type ProcessedTx, type PublicKernelRequest, type SimulationError, @@ -13,7 +14,6 @@ import { } from '@aztec/circuit-types'; import { type TxSequencerProcessingStats } from '@aztec/circuit-types/stats'; import { type GlobalVariables, type Header, type KernelCircuitPublicInputs } from '@aztec/circuits.js'; -import { type ProcessReturnValues } from '@aztec/foundation/abi'; import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; import { PublicExecutor, type PublicStateDB, type SimulationProvider } from '@aztec/simulator'; diff --git a/yarn-project/simulator/src/public/setup_phase_manager.test.ts b/yarn-project/simulator/src/public/setup_phase_manager.test.ts index b90c2a0147de..c8be4e8a64c1 100644 --- a/yarn-project/simulator/src/public/setup_phase_manager.test.ts +++ b/yarn-project/simulator/src/public/setup_phase_manager.test.ts @@ -12,7 +12,7 @@ import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simul import { SetupPhaseManager } from './setup_phase_manager.js'; class TestSetupPhaseManager extends SetupPhaseManager { - extractEnqueuedPublicCalls(tx: any) { + override extractEnqueuedPublicCalls(tx: any) { return super.extractEnqueuedPublicCalls(tx); } } diff --git a/yarn-project/simulator/src/public/setup_phase_manager.ts b/yarn-project/simulator/src/public/setup_phase_manager.ts index 591cc5814e2e..9c21f610a16a 100644 --- a/yarn-project/simulator/src/public/setup_phase_manager.ts +++ b/yarn-project/simulator/src/public/setup_phase_manager.ts @@ -17,14 +17,14 @@ import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simul */ export class SetupPhaseManager extends AbstractPhaseManager { constructor( - protected db: MerkleTreeOperations, - protected publicExecutor: PublicExecutor, - protected publicKernel: PublicKernelCircuitSimulator, - protected globalVariables: GlobalVariables, - protected historicalHeader: Header, + db: MerkleTreeOperations, + publicExecutor: PublicExecutor, + publicKernel: PublicKernelCircuitSimulator, + globalVariables: GlobalVariables, + historicalHeader: Header, protected publicContractsDB: ContractsDataSourcePublicDB, protected publicStateDB: PublicStateDB, - public phase: PublicKernelPhase = PublicKernelPhase.SETUP, + phase: PublicKernelPhase = PublicKernelPhase.SETUP, ) { super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase); } diff --git a/yarn-project/simulator/src/public/state_actions.ts b/yarn-project/simulator/src/public/state_actions.ts index a4b63c54a604..cd25d82f669f 100644 --- a/yarn-project/simulator/src/public/state_actions.ts +++ b/yarn-project/simulator/src/public/state_actions.ts @@ -83,6 +83,7 @@ export class ContractStorageActionsCollector { public collect(): [ContractStorageRead[], ContractStorageUpdateRequest[]] { const reads = Array.from(this.contractStorageReads.entries()).map(([slot, valueAndCounter]) => ContractStorageRead.from({ + contractAddress: this.address, storageSlot: new Fr(slot), ...valueAndCounter, }), @@ -90,6 +91,7 @@ export class ContractStorageActionsCollector { const updateRequests = Array.from(this.contractStorageUpdateRequests.entries()).map(([slot, valuesAndCounter]) => ContractStorageUpdateRequest.from({ + contractAddress: this.address, storageSlot: new Fr(slot), ...valuesAndCounter, }), diff --git a/yarn-project/simulator/src/public/tail_phase_manager.ts b/yarn-project/simulator/src/public/tail_phase_manager.ts index 0cc78be521f9..c5c3487f1a9c 100644 --- a/yarn-project/simulator/src/public/tail_phase_manager.ts +++ b/yarn-project/simulator/src/public/tail_phase_manager.ts @@ -1,14 +1,23 @@ -import { type PublicKernelRequest, PublicKernelType, type Tx } from '@aztec/circuit-types'; import { - type Fr, + type PublicKernelRequest, + PublicKernelType, + type Tx, + UnencryptedFunctionL2Logs, + type UnencryptedL2Log, +} from '@aztec/circuit-types'; +import { + Fr, type GlobalVariables, type Header, type KernelCircuitPublicInputs, MAX_NEW_NOTE_HASHES_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + type MAX_UNENCRYPTED_LOGS_PER_TX, type Proof, type PublicKernelCircuitPublicInputs, PublicKernelTailCircuitPrivateInputs, - type SideEffect, + SideEffect, makeEmptyProof, mergeAccumulatedData, sortByCounter, @@ -23,14 +32,14 @@ import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simul export class TailPhaseManager extends AbstractPhaseManager { constructor( - protected db: MerkleTreeOperations, - protected publicExecutor: PublicExecutor, - protected publicKernel: PublicKernelCircuitSimulator, - protected globalVariables: GlobalVariables, - protected historicalHeader: Header, + db: MerkleTreeOperations, + publicExecutor: PublicExecutor, + publicKernel: PublicKernelCircuitSimulator, + globalVariables: GlobalVariables, + historicalHeader: Header, protected publicContractsDB: ContractsDataSourcePublicDB, protected publicStateDB: PublicStateDB, - public readonly phase: PublicKernelPhase = PublicKernelPhase.TAIL, + phase: PublicKernelPhase = PublicKernelPhase.TAIL, ) { super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase); } @@ -47,7 +56,8 @@ export class TailPhaseManager extends AbstractPhaseManager { throw err; }, ); - + // Temporary hack. Should sort them in the tail circuit. + this.patchLogsOrdering(tx, previousPublicKernelOutput); // commit the state updates from this transaction await this.publicStateDB.commit(); @@ -71,6 +81,10 @@ export class TailPhaseManager extends AbstractPhaseManager { previousOutput: PublicKernelCircuitPublicInputs, previousProof: Proof, ): Promise<[PublicKernelTailCircuitPrivateInputs, KernelCircuitPublicInputs]> { + // Temporary hack. Should sort them in the tail circuit. + previousOutput.end.unencryptedLogsHashes = this.sortLogsHashes( + previousOutput.end.unencryptedLogsHashes, + ); const [inputs, output] = await this.simulate(previousOutput, previousProof); // Temporary hack. Should sort them in the tail circuit. @@ -88,25 +102,59 @@ export class TailPhaseManager extends AbstractPhaseManager { previousOutput: PublicKernelCircuitPublicInputs, previousProof: Proof, ): Promise<[PublicKernelTailCircuitPrivateInputs, KernelCircuitPublicInputs]> { + const inputs = await this.buildPrivateInputs(previousOutput, previousProof); + // We take a deep copy (clone) of these to pass to the prover + return [inputs.clone(), await this.publicKernel.publicKernelCircuitTail(inputs)]; + } + + private async buildPrivateInputs(previousOutput: PublicKernelCircuitPublicInputs, previousProof: Proof) { const previousKernel = this.getPreviousKernelData(previousOutput, previousProof); const { validationRequests, endNonRevertibleData, end } = previousOutput; - const nullifierReadRequestHints = await this.hintsBuilder.getNullifierReadRequestHints( - validationRequests.nullifierReadRequests, + + const pendingNullifiers = mergeAccumulatedData( + MAX_NEW_NULLIFIERS_PER_TX, endNonRevertibleData.newNullifiers, end.newNullifiers, ); + + const nullifierReadRequestHints = await this.hintsBuilder.getNullifierReadRequestHints( + validationRequests.nullifierReadRequests, + pendingNullifiers, + ); + const nullifierNonExistentReadRequestHints = await this.hintsBuilder.getNullifierNonExistentReadRequestHints( validationRequests.nullifierNonExistentReadRequests, - endNonRevertibleData.newNullifiers, - end.newNullifiers, + pendingNullifiers, + ); + + const pendingPublicDataWrites = mergeAccumulatedData( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + endNonRevertibleData.publicDataUpdateRequests, + end.publicDataUpdateRequests, + ); + + const publicDataHints = await this.hintsBuilder.getPublicDataHints( + validationRequests.publicDataReads, + pendingPublicDataWrites, + ); + + const publicDataReadRequestHints = this.hintsBuilder.getPublicDataReadRequestHints( + validationRequests.publicDataReads, + pendingPublicDataWrites, + publicDataHints, ); - const inputs = new PublicKernelTailCircuitPrivateInputs( + + const currentState = await this.db.getStateReference(); + + return new PublicKernelTailCircuitPrivateInputs( previousKernel, nullifierReadRequestHints, nullifierNonExistentReadRequestHints, + publicDataHints, + publicDataReadRequestHints, + currentState.partial, ); - return [inputs, await this.publicKernel.publicKernelCircuitTail(inputs)]; } private sortNoteHashes(noteHashes: Tuple): Tuple { @@ -115,4 +163,35 @@ export class TailPhaseManager extends AbstractPhaseManager { N >; } + + private sortLogsHashes(unencryptedLogsHashes: Tuple): Tuple { + return sortByCounter(unencryptedLogsHashes.map(n => ({ ...n, counter: n.counter.toNumber() }))).map( + h => new SideEffect(h.value, new Fr(h.counter)), + ) as Tuple; + } + + // As above, this is a hack for unencrypted logs ordering, now they are sorted. Since the public kernel + // cannot keep track of side effects that happen after or before a nested call, we override the gathered logs. + // As a sanity check, we at least verify that the elements are the same, so we are only tweaking their ordering. + // See same fn in pxe_service.ts + // Added as part of resolving #5017 + private patchLogsOrdering(tx: Tx, publicInputs: PublicKernelCircuitPublicInputs) { + const unencLogs = tx.unencryptedLogs.unrollLogs(); + const sortedUnencLogs = publicInputs.end.unencryptedLogsHashes; + + const finalUnencLogs: UnencryptedL2Log[] = []; + sortedUnencLogs.forEach((sideEffect: SideEffect) => { + if (!sideEffect.isEmpty()) { + const isLog = (log: UnencryptedL2Log) => Fr.fromBuffer(log.hash()).equals(sideEffect.value); + const thisLogIndex = unencLogs.findIndex(isLog); + finalUnencLogs.push(unencLogs[thisLogIndex]); + } + }); + const unencryptedLogs = new UnencryptedFunctionL2Logs(finalUnencLogs); + + tx.unencryptedLogs.functionLogs[0] = unencryptedLogs; + for (let i = 1; i < tx.unencryptedLogs.functionLogs.length; i++) { + tx.unencryptedLogs.functionLogs[i] = UnencryptedFunctionL2Logs.empty(); + } + } } diff --git a/yarn-project/simulator/src/public/teardown_phase_manager.ts b/yarn-project/simulator/src/public/teardown_phase_manager.ts index 5d6cff3a3bd0..c5e84807227c 100644 --- a/yarn-project/simulator/src/public/teardown_phase_manager.ts +++ b/yarn-project/simulator/src/public/teardown_phase_manager.ts @@ -17,14 +17,14 @@ import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simul */ export class TeardownPhaseManager extends AbstractPhaseManager { constructor( - protected db: MerkleTreeOperations, - protected publicExecutor: PublicExecutor, - protected publicKernel: PublicKernelCircuitSimulator, - protected globalVariables: GlobalVariables, - protected historicalHeader: Header, + db: MerkleTreeOperations, + publicExecutor: PublicExecutor, + publicKernel: PublicKernelCircuitSimulator, + globalVariables: GlobalVariables, + historicalHeader: Header, protected publicContractsDB: ContractsDataSourcePublicDB, protected publicStateDB: PublicStateDB, - public phase: PublicKernelPhase = PublicKernelPhase.TEARDOWN, + phase: PublicKernelPhase = PublicKernelPhase.TEARDOWN, ) { super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase); } diff --git a/yarn-project/simulator/src/public/transitional_adaptors.ts b/yarn-project/simulator/src/public/transitional_adaptors.ts index 567852b124ef..81cd68ebab09 100644 --- a/yarn-project/simulator/src/public/transitional_adaptors.ts +++ b/yarn-project/simulator/src/public/transitional_adaptors.ts @@ -5,7 +5,7 @@ import { ContractStorageRead, ContractStorageUpdateRequest, FunctionData, - GasSettings, + Gas, type GlobalVariables, type Header, L2ToL1Message, @@ -17,6 +17,7 @@ import { Fr } from '@aztec/foundation/fields'; import { type AvmContext } from '../avm/avm_context.js'; import { AvmExecutionEnvironment } from '../avm/avm_execution_environment.js'; +import { type AvmMachineState } from '../avm/avm_machine_state.js'; import { AvmContractCallResults } from '../avm/avm_message_call_result.js'; import { type JournalData } from '../avm/journal/journal.js'; import { Mov } from '../avm/opcodes/memory.js'; @@ -40,18 +41,19 @@ export function createAvmExecutionEnvironment( return new AvmExecutionEnvironment( current.contractAddress, current.callContext.storageContractAddress, - current.callContext.msgSender, // TODO: origin is not available current.callContext.msgSender, current.callContext.portalContractAddress, - /*feePerL1Gas=*/ Fr.zero(), - /*feePerL2Gas=*/ Fr.zero(), - /*feePerDaGas=*/ Fr.zero(), + globalVariables.gasFees.feePerL1Gas, + globalVariables.gasFees.feePerL2Gas, + globalVariables.gasFees.feePerDaGas, /*contractCallDepth=*/ Fr.zero(), header, globalVariables, current.callContext.isStaticCall, current.callContext.isDelegateCall, current.args, + current.callContext.gasSettings, + current.callContext.transactionFee, current.functionData.selector, ); } @@ -63,11 +65,12 @@ export function createPublicExecutionContext(avmContext: AvmContext, calldata: F storageContractAddress: avmContext.environment.storageAddress, portalContractAddress: avmContext.environment.portal, functionSelector: avmContext.environment.temporaryFunctionSelector, + gasLeft: Gas.from(avmContext.machineState.gasLeft), isDelegateCall: avmContext.environment.isDelegateCall, isStaticCall: avmContext.environment.isStaticCall, sideEffectCounter: sideEffectCounter, - gasSettings: GasSettings.empty(), // TODO(palla/gas-in-circuits) - transactionFee: Fr.ZERO, // TODO(palla/gas-in-circuits) + gasSettings: avmContext.environment.gasSettings, + transactionFee: avmContext.environment.transactionFee, }); const functionData = new FunctionData(avmContext.environment.temporaryFunctionSelector, /*isPrivate=*/ false); const execution: PublicExecution = { @@ -104,14 +107,15 @@ export async function convertAvmResults( executionContext: PublicExecutionContext, newWorldState: JournalData, result: AvmContractCallResults, + endMachineState: AvmMachineState, ): Promise { const execution = executionContext.execution; const contractStorageReads: ContractStorageRead[] = newWorldState.storageReads.map( - read => new ContractStorageRead(read.slot, read.value, read.counter.toNumber()), + read => new ContractStorageRead(read.slot, read.value, read.counter.toNumber(), read.storageAddress), ); const contractStorageUpdateRequests: ContractStorageUpdateRequest[] = newWorldState.storageWrites.map( - write => new ContractStorageUpdateRequest(write.slot, write.value, write.counter.toNumber()), + write => new ContractStorageUpdateRequest(write.slot, write.value, write.counter.toNumber(), write.storageAddress), ); // We need to write the storage updates to the DB, because that's what the ACVM expects. // Assumes the updates are in the right order. @@ -139,6 +143,9 @@ export async function convertAvmResults( const unencryptedLogs: UnencryptedFunctionL2Logs = new UnencryptedFunctionL2Logs( newWorldState.newLogs.map(log => new UnencryptedL2Log(log.contractAddress, log.selector, log.data)), ); + const unencryptedLogsHashes = newWorldState.newLogsHashes.map( + logHash => new SideEffect(logHash.logHash, logHash.counter), + ); const newL2ToL1Messages = newWorldState.newL1Messages.map(m => new L2ToL1Message(m.recipient, m.content)); const returnValues = result.output; @@ -162,9 +169,11 @@ export async function convertAvmResults( contractStorageUpdateRequests, returnValues, nestedExecutions, + unencryptedLogsHashes, unencryptedLogs, reverted: result.reverted, revertReason: result.revertReason ? createSimulationError(result.revertReason) : undefined, + gasLeft: endMachineState.gasLeft, }; } diff --git a/yarn-project/simulator/src/public/utils.ts b/yarn-project/simulator/src/public/utils.ts index 8918c39030bb..7a2fae3b78eb 100644 --- a/yarn-project/simulator/src/public/utils.ts +++ b/yarn-project/simulator/src/public/utils.ts @@ -14,6 +14,7 @@ export function lastSideEffectCounter(tx: Tx): number { ...data.endNonRevertibleData.publicCallStack, ...data.end.newNoteHashes, ...data.end.newNullifiers, + ...data.end.unencryptedLogsHashes, ...data.end.publicCallStack, ]; diff --git a/yarn-project/simulator/src/simulator/acvm_wasm.ts b/yarn-project/simulator/src/simulator/acvm_wasm.ts index 16e83ddda1b1..d78838427785 100644 --- a/yarn-project/simulator/src/simulator/acvm_wasm.ts +++ b/yarn-project/simulator/src/simulator/acvm_wasm.ts @@ -1,3 +1,4 @@ +import { foreignCallHandler } from '@aztec/noir-protocol-circuits-types'; import { type NoirCompiledCircuit } from '@aztec/types/noir'; import { @@ -26,9 +27,12 @@ export class WASMSimulator implements SimulationProvider { const decodedBytecode = Buffer.from(compiledCircuit.bytecode, 'base64'); // // Execute the circuit - const _witnessMap = await executeCircuitWithBlackBoxSolver(await getSolver(), decodedBytecode, input, () => { - throw Error('unexpected oracle during execution'); - }); + const _witnessMap = await executeCircuitWithBlackBoxSolver( + await getSolver(), + decodedBytecode, + input, + foreignCallHandler, // handle calls to debug_log + ); return _witnessMap; } diff --git a/yarn-project/tsconfig.json b/yarn-project/tsconfig.json index 887a5e3c4ebc..eafb807f772f 100644 --- a/yarn-project/tsconfig.json +++ b/yarn-project/tsconfig.json @@ -15,7 +15,8 @@ "importHelpers": true, "resolveJsonModule": true, "composite": true, - "skipLibCheck": true + "skipLibCheck": true, + "noImplicitOverride": true }, "references": [ { "path": "accounts/tsconfig.json" }, diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index b1b5ca3d8ac8..f2c605a08864 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -117,9 +117,10 @@ type NoirCompiledContractFunction = NoirCompiledContract['functions'][number]; /** * Generates a function build artifact. Replaces verification key with a mock value. * @param fn - Noir function entry. + * @param contract - Parent contract. * @returns Function artifact. */ -function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArtifact { +function generateFunctionArtifact(fn: NoirCompiledContractFunction, contract: NoirCompiledContract): FunctionArtifact { if (fn.custom_attributes === undefined) { throw new Error( `No custom attributes found for contract function ${fn.name}. Try rebuilding the contract with the latest nargo version.`, @@ -134,10 +135,25 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArt parameters = parameters.slice(1); } - // If the function is secret, the return is the public inputs, which should be omitted let returnTypes: AbiType[] = []; - if (functionType !== 'secret' && fn.abi.return_type) { + if (functionType === FunctionType.UNCONSTRAINED && fn.abi.return_type) { returnTypes = [fn.abi.return_type.abi_type]; + } else { + const pathToFind = `${contract.name}::${fn.name}_abi`; + const abiStructs: AbiType[] = contract.outputs.structs['functions']; + + const returnStruct = abiStructs.find(a => a.kind === 'struct' && a.path === pathToFind); + + if (returnStruct) { + if (returnStruct.kind !== 'struct') { + throw new Error('Could not generate contract function artifact'); + } + + const returnTypeField = returnStruct.fields.find(field => field.name === 'return_type'); + if (returnTypeField) { + returnTypes = [returnTypeField.type]; + } + } } return { @@ -190,7 +206,7 @@ function hasKernelFunctionInputs(params: ABIParameter[]): boolean { function generateContractArtifact(contract: NoirCompiledContract, aztecNrVersion?: string): ContractArtifact { return { name: contract.name, - functions: contract.functions.map(generateFunctionArtifact), + functions: contract.functions.map(f => generateFunctionArtifact(f, contract)), outputs: contract.outputs, fileMap: contract.file_map, aztecNrVersion, diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 23adca3a1b68..1121959ee0b8 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -103,7 +103,6 @@ __metadata: debug: ^4.3.4 jest: ^29.5.0 jest-mock-extended: ^3.0.4 - lmdb: ^2.9.2 lodash.groupby: ^4.6.0 lodash.omit: ^4.5.0 ts-node: ^10.9.1 @@ -556,7 +555,7 @@ __metadata: "@types/node": ^18.7.23 jest: ^29.5.0 jest-mock-extended: ^3.0.3 - lmdb: ^2.9.2 + lmdb: ^3.0.6 ts-node: ^10.9.1 typescript: ^5.0.4 languageName: unknown @@ -607,6 +606,7 @@ __metadata: "@types/jest": ^29.5.0 "@types/lodash.camelcase": ^4.3.7 "@types/lodash.capitalize": ^4.2.7 + "@types/lodash.uniqby": ^4.7.9 "@types/node": ^18.7.23 "@types/pako": ^2.0.0 "@types/semver": ^7.5.4 @@ -616,6 +616,7 @@ __metadata: jest: ^29.5.0 lodash.camelcase: ^4.3.0 lodash.capitalize: ^4.2.1 + lodash.uniqby: ^4.7.0 memfs: ^4.6.0 pako: ^2.1.0 semver: ^7.5.4 @@ -2563,44 +2564,44 @@ __metadata: languageName: node linkType: hard -"@lmdb/lmdb-darwin-arm64@npm:2.9.2": - version: 2.9.2 - resolution: "@lmdb/lmdb-darwin-arm64@npm:2.9.2" +"@lmdb/lmdb-darwin-arm64@npm:3.0.6": + version: 3.0.6 + resolution: "@lmdb/lmdb-darwin-arm64@npm:3.0.6" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@lmdb/lmdb-darwin-x64@npm:2.9.2": - version: 2.9.2 - resolution: "@lmdb/lmdb-darwin-x64@npm:2.9.2" +"@lmdb/lmdb-darwin-x64@npm:3.0.6": + version: 3.0.6 + resolution: "@lmdb/lmdb-darwin-x64@npm:3.0.6" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@lmdb/lmdb-linux-arm64@npm:2.9.2": - version: 2.9.2 - resolution: "@lmdb/lmdb-linux-arm64@npm:2.9.2" +"@lmdb/lmdb-linux-arm64@npm:3.0.6": + version: 3.0.6 + resolution: "@lmdb/lmdb-linux-arm64@npm:3.0.6" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@lmdb/lmdb-linux-arm@npm:2.9.2": - version: 2.9.2 - resolution: "@lmdb/lmdb-linux-arm@npm:2.9.2" +"@lmdb/lmdb-linux-arm@npm:3.0.6": + version: 3.0.6 + resolution: "@lmdb/lmdb-linux-arm@npm:3.0.6" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@lmdb/lmdb-linux-x64@npm:2.9.2": - version: 2.9.2 - resolution: "@lmdb/lmdb-linux-x64@npm:2.9.2" +"@lmdb/lmdb-linux-x64@npm:3.0.6": + version: 3.0.6 + resolution: "@lmdb/lmdb-linux-x64@npm:3.0.6" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@lmdb/lmdb-win32-x64@npm:2.9.2": - version: 2.9.2 - resolution: "@lmdb/lmdb-win32-x64@npm:2.9.2" +"@lmdb/lmdb-win32-x64@npm:3.0.6": + version: 3.0.6 + resolution: "@lmdb/lmdb-win32-x64@npm:3.0.6" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -3634,6 +3635,15 @@ __metadata: languageName: node linkType: hard +"@types/lodash.uniqby@npm:^4.7.9": + version: 4.7.9 + resolution: "@types/lodash.uniqby@npm:4.7.9" + dependencies: + "@types/lodash": "*" + checksum: 24cc8af36e0d4c52b7294c7ba7d814c89ce2c8118d94350bbed21031fef850fa1a280bfd2b30a47e0b5f7aa6ac649a36a5089aa76bc23787963a5ee6443f631e + languageName: node + linkType: hard + "@types/lodash@npm:*": version: 4.14.202 resolution: "@types/lodash@npm:4.14.202" @@ -9674,16 +9684,16 @@ __metadata: languageName: node linkType: hard -"lmdb@npm:^2.9.2": - version: 2.9.2 - resolution: "lmdb@npm:2.9.2" - dependencies: - "@lmdb/lmdb-darwin-arm64": 2.9.2 - "@lmdb/lmdb-darwin-x64": 2.9.2 - "@lmdb/lmdb-linux-arm": 2.9.2 - "@lmdb/lmdb-linux-arm64": 2.9.2 - "@lmdb/lmdb-linux-x64": 2.9.2 - "@lmdb/lmdb-win32-x64": 2.9.2 +"lmdb@npm:^3.0.6": + version: 3.0.6 + resolution: "lmdb@npm:3.0.6" + dependencies: + "@lmdb/lmdb-darwin-arm64": 3.0.6 + "@lmdb/lmdb-darwin-x64": 3.0.6 + "@lmdb/lmdb-linux-arm": 3.0.6 + "@lmdb/lmdb-linux-arm64": 3.0.6 + "@lmdb/lmdb-linux-x64": 3.0.6 + "@lmdb/lmdb-win32-x64": 3.0.6 msgpackr: ^1.9.9 node-addon-api: ^6.1.0 node-gyp: latest @@ -9705,7 +9715,7 @@ __metadata: optional: true bin: download-lmdb-prebuilds: bin/download-prebuilds.js - checksum: b2471c4d2c36f15a27233ae1eece86fcbb40613574ec54245cf697b16b1b35c70c72e4092dc739407df145f14b7c1b6b56c4281a439c314e79a5338df8b2b63b + checksum: e8ab5bbef94e254ec1fa85deec251c4b34047786c87f54abd842cd12c3f29d55f62828512a4b69046075a624a25b2327e232072be702a68fcb3d8183e0175cca languageName: node linkType: hard @@ -9844,6 +9854,13 @@ __metadata: languageName: node linkType: hard +"lodash.uniqby@npm:^4.7.0": + version: 4.7.0 + resolution: "lodash.uniqby@npm:4.7.0" + checksum: 659264545a95726d1493123345aad8cbf56e17810fa9a0b029852c6d42bc80517696af09d99b23bef1845d10d95e01b8b4a1da578f22aeba7a30d3e0022a4938 + languageName: node + linkType: hard + "lodash@npm:^4.17.21, lodash@npm:^4.17.4": version: 4.17.21 resolution: "lodash@npm:4.17.21" diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index fb57ccd13afb..000000000000 --- a/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - diff --git a/yellow-paper/.gitignore b/yellow-paper/.gitignore deleted file mode 100644 index b2d6de30624f..000000000000 --- a/yellow-paper/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# Dependencies -/node_modules - -# Production -/build - -# Generated files -.docusaurus -.cache-loader - -# Misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/yellow-paper/Dockerfile b/yellow-paper/Dockerfile deleted file mode 100644 index ab8cb91196d8..000000000000 --- a/yellow-paper/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM node:18.19.0-alpine -WORKDIR /usr/src -COPY . . -RUN yarn && yarn build --no-minify \ No newline at end of file diff --git a/yellow-paper/README.md b/yellow-paper/README.md deleted file mode 100644 index aaba2fa1e16e..000000000000 --- a/yellow-paper/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# Website - -This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. - -### Installation - -``` -$ yarn -``` - -### Local Development - -``` -$ yarn start -``` - -This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. - -### Build - -``` -$ yarn build -``` - -This command generates static content into the `build` directory and can be served using any static contents hosting service. - -### Deployment - -Using SSH: - -``` -$ USE_SSH=true yarn deploy -``` - -Not using SSH: - -``` -$ GIT_USER= yarn deploy -``` - -If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/yellow-paper/babel.config.js b/yellow-paper/babel.config.js deleted file mode 100644 index e00595dae7d6..000000000000 --- a/yellow-paper/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: [require.resolve('@docusaurus/core/lib/babel/preset')], -}; diff --git a/yellow-paper/docs-tutorial-reference/intro.md b/yellow-paper/docs-tutorial-reference/intro.md deleted file mode 100644 index 8a2e69d95f9f..000000000000 --- a/yellow-paper/docs-tutorial-reference/intro.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Tutorial Intro - -Let's discover **Docusaurus in less than 5 minutes**. - -## Getting Started - -Get started by **creating a new site**. - -Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new)**. - -### What you'll need - -- [Node.js](https://nodejs.org/en/download/) version 16.14 or above: - - When installing Node.js, you are recommended to check all checkboxes related to dependencies. - -## Generate a new site - -Generate a new Docusaurus site using the **classic template**. - -The classic template will automatically be added to your project after you run the command: - -```bash -npm init docusaurus@latest my-website classic -``` - -You can type this command into Command Prompt, Powershell, Terminal, or any other integrated terminal of your code editor. - -The command also installs all necessary dependencies you need to run Docusaurus. - -## Start your site - -Run the development server: - -```bash -cd my-website -npm run start -``` - -The `cd` command changes the directory you're working with. In order to work with your newly created Docusaurus site, you'll need to navigate the terminal there. - -The `npm run start` command builds your website locally and serves it through a development server, ready for you to view at http://localhost:3000/. - -Open `docs/intro.md` (this page) and edit some lines: the site **reloads automatically** and displays your changes. diff --git a/yellow-paper/docs-tutorial-reference/tutorial-basics/_category_.json b/yellow-paper/docs-tutorial-reference/tutorial-basics/_category_.json deleted file mode 100644 index 2e6db55b1eb6..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-basics/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Tutorial - Basics", - "position": 2, - "link": { - "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." - } -} diff --git a/yellow-paper/docs-tutorial-reference/tutorial-basics/congratulations.md b/yellow-paper/docs-tutorial-reference/tutorial-basics/congratulations.md deleted file mode 100644 index 04771a00b72f..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-basics/congratulations.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar_position: 6 ---- - -# Congratulations! - -You have just learned the **basics of Docusaurus** and made some changes to the **initial template**. - -Docusaurus has **much more to offer**! - -Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**. - -Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610) - -## What's next? - -- Read the [official documentation](https://docusaurus.io/) -- Modify your site configuration with [`docusaurus.config.js`](https://docusaurus.io/docs/api/docusaurus-config) -- Add navbar and footer items with [`themeConfig`](https://docusaurus.io/docs/api/themes/configuration) -- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout) -- Add a [search bar](https://docusaurus.io/docs/search) -- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase) -- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support) diff --git a/yellow-paper/docs-tutorial-reference/tutorial-basics/create-a-blog-post.md b/yellow-paper/docs-tutorial-reference/tutorial-basics/create-a-blog-post.md deleted file mode 100644 index ea472bbaf871..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-basics/create-a-blog-post.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Create a Blog Post - -Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed... - -## Create your first Post - -Create a file at `blog/2021-02-28-greetings.md`: - -```md title="blog/2021-02-28-greetings.md" ---- -slug: greetings -title: Greetings! -authors: - - name: Joel Marcey - title: Co-creator of Docusaurus 1 - url: https://github.com/JoelMarcey - image_url: https://github.com/JoelMarcey.png - - name: Sébastien Lorber - title: Docusaurus maintainer - url: https://sebastienlorber.com - image_url: https://github.com/slorber.png -tags: [greetings] ---- - -Congratulations, you have made your first post! - -Feel free to play around and edit this post as much you like. -``` - -A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings). diff --git a/yellow-paper/docs-tutorial-reference/tutorial-basics/create-a-document.md b/yellow-paper/docs-tutorial-reference/tutorial-basics/create-a-document.md deleted file mode 100644 index ffddfa8eb8ac..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-basics/create-a-document.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Create a Document - -Documents are **groups of pages** connected through: - -- a **sidebar** -- **previous/next navigation** -- **versioning** - -## Create your first Doc - -Create a Markdown file at `docs/hello.md`: - -```md title="docs/hello.md" -# Hello - -This is my **first Docusaurus document**! -``` - -A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello). - -## Configure the Sidebar - -Docusaurus automatically **creates a sidebar** from the `docs` folder. - -Add metadata to customize the sidebar label and position: - -```md title="docs/hello.md" {1-4} ---- -sidebar_label: 'Hi!' -sidebar_position: 3 ---- - -# Hello - -This is my **first Docusaurus document**! -``` - -It is also possible to create your sidebar explicitly in `sidebars.js`: - -```js title="sidebars.js" -module.exports = { - tutorialSidebar: [ - 'intro', - // highlight-next-line - 'hello', - { - type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], - }, - ], -}; -``` diff --git a/yellow-paper/docs-tutorial-reference/tutorial-basics/create-a-page.md b/yellow-paper/docs-tutorial-reference/tutorial-basics/create-a-page.md deleted file mode 100644 index 20e2ac300556..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-basics/create-a-page.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Create a Page - -Add **Markdown or React** files to `src/pages` to create a **standalone page**: - -- `src/pages/index.js` → `localhost:3000/` -- `src/pages/foo.md` → `localhost:3000/foo` -- `src/pages/foo/bar.js` → `localhost:3000/foo/bar` - -## Create your first React Page - -Create a file at `src/pages/my-react-page.js`: - -```jsx title="src/pages/my-react-page.js" -import React from 'react'; -import Layout from '@theme/Layout'; - -export default function MyReactPage() { - return ( - -

My React page

-

This is a React page

-
- ); -} -``` - -A new page is now available at [http://localhost:3000/my-react-page](http://localhost:3000/my-react-page). - -## Create your first Markdown Page - -Create a file at `src/pages/my-markdown-page.md`: - -```mdx title="src/pages/my-markdown-page.md" -# My Markdown page - -This is a Markdown page -``` - -A new page is now available at [http://localhost:3000/my-markdown-page](http://localhost:3000/my-markdown-page). diff --git a/yellow-paper/docs-tutorial-reference/tutorial-basics/deploy-your-site.md b/yellow-paper/docs-tutorial-reference/tutorial-basics/deploy-your-site.md deleted file mode 100644 index 1c50ee063ef4..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-basics/deploy-your-site.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Deploy your site - -Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**). - -It builds your site as simple **static HTML, JavaScript and CSS files**. - -## Build your site - -Build your site **for production**: - -```bash -npm run build -``` - -The static files are generated in the `build` folder. - -## Deploy your site - -Test your production build locally: - -```bash -npm run serve -``` - -The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/). - -You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**). diff --git a/yellow-paper/docs-tutorial-reference/tutorial-basics/markdown-features.mdx b/yellow-paper/docs-tutorial-reference/tutorial-basics/markdown-features.mdx deleted file mode 100644 index 0337f34d6a54..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-basics/markdown-features.mdx +++ /dev/null @@ -1,150 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Markdown Features - -Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**. - -## Front Matter - -Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/): - -```text title="my-doc.md" -// highlight-start ---- -id: my-doc-id -title: My document title -description: My document description -slug: /my-custom-url ---- -// highlight-end - -## Markdown heading - -Markdown text with [links](./hello.md) -``` - -## Links - -Regular Markdown links are supported, using url paths or relative file paths. - -```md -Let's see how to [Create a page](/create-a-page). -``` - -```md -Let's see how to [Create a page](./create-a-page.md). -``` - -**Result:** Let's see how to [Create a page](./create-a-page.md). - -## Images - -Regular Markdown images are supported. - -You can use absolute paths to reference images in the static directory (`static/img/docusaurus.png`): - -```md -![Docusaurus logo](/img/docusaurus.png) -``` - -![Docusaurus logo](/img/docusaurus.png) - -You can reference images relative to the current file as well. This is particularly useful to colocate images close to the Markdown files using them: - -```md -![Docusaurus logo](./img/docusaurus.png) -``` - -## Code Blocks - -Markdown code blocks are supported with Syntax highlighting. - - ```jsx title="src/components/HelloDocusaurus.js" - function HelloDocusaurus() { - return ( -

Hello, Docusaurus!

- ) - } - ``` - -```jsx title="src/components/HelloDocusaurus.js" -function HelloDocusaurus() { - return

Hello, Docusaurus!

; -} -``` - -## Admonitions - -Docusaurus has a special syntax to create admonitions and callouts: - - :::tip My tip - - Use this awesome feature option - - ::: - - :::danger Take care - - This action is dangerous - - ::: - -:::tip My tip - -Use this awesome feature option - -::: - -:::danger Take care - -This action is dangerous - -::: - -## MDX and React Components - -[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**: - -```jsx -export const Highlight = ({children, color}) => ( - { - alert(`You clicked the color ${color} with label ${children}`) - }}> - {children} - -); - -This is Docusaurus green ! - -This is Facebook blue ! -``` - -export const Highlight = ({children, color}) => ( - { - alert(`You clicked the color ${color} with label ${children}`); - }}> - {children} - -); - -This is Docusaurus green ! - -This is Facebook blue ! diff --git a/yellow-paper/docs-tutorial-reference/tutorial-extras/_category_.json b/yellow-paper/docs-tutorial-reference/tutorial-extras/_category_.json deleted file mode 100644 index a8ffcc19300e..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-extras/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Tutorial - Extras", - "position": 3, - "link": { - "type": "generated-index" - } -} diff --git a/yellow-paper/docs-tutorial-reference/tutorial-extras/img/docsVersionDropdown.png b/yellow-paper/docs-tutorial-reference/tutorial-extras/img/docsVersionDropdown.png deleted file mode 100644 index 97e4164618b5..000000000000 Binary files a/yellow-paper/docs-tutorial-reference/tutorial-extras/img/docsVersionDropdown.png and /dev/null differ diff --git a/yellow-paper/docs-tutorial-reference/tutorial-extras/img/localeDropdown.png b/yellow-paper/docs-tutorial-reference/tutorial-extras/img/localeDropdown.png deleted file mode 100644 index e257edc1f932..000000000000 Binary files a/yellow-paper/docs-tutorial-reference/tutorial-extras/img/localeDropdown.png and /dev/null differ diff --git a/yellow-paper/docs-tutorial-reference/tutorial-extras/manage-docs-versions.md b/yellow-paper/docs-tutorial-reference/tutorial-extras/manage-docs-versions.md deleted file mode 100644 index e12c3f3444fa..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-extras/manage-docs-versions.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Manage Docs Versions - -Docusaurus can manage multiple versions of your docs. - -## Create a docs version - -Release a version 1.0 of your project: - -```bash -npm run docusaurus docs:version 1.0 -``` - -The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created. - -Your docs now have 2 versions: - -- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs -- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs** - -## Add a Version Dropdown - -To navigate seamlessly across versions, add a version dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -module.exports = { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'docsVersionDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The docs version dropdown appears in your navbar: - -![Docs Version Dropdown](./img/docsVersionDropdown.png) - -## Update an existing version - -It is possible to edit versioned docs in their respective folder: - -- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello` -- `docs/hello.md` updates `http://localhost:3000/docs/next/hello` diff --git a/yellow-paper/docs-tutorial-reference/tutorial-extras/translate-your-site.md b/yellow-paper/docs-tutorial-reference/tutorial-extras/translate-your-site.md deleted file mode 100644 index caeaffb05548..000000000000 --- a/yellow-paper/docs-tutorial-reference/tutorial-extras/translate-your-site.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Translate your site - -Let's translate `docs/intro.md` to French. - -## Configure i18n - -Modify `docusaurus.config.js` to add support for the `fr` locale: - -```js title="docusaurus.config.js" -module.exports = { - i18n: { - defaultLocale: 'en', - locales: ['en', 'fr'], - }, -}; -``` - -## Translate a doc - -Copy the `docs/intro.md` file to the `i18n/fr` folder: - -```bash -mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/ - -cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md -``` - -Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French. - -## Start your localized site - -Start your site on the French locale: - -```bash -npm run start -- --locale fr -``` - -Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated. - -:::caution - -In development, you can only use one locale at a same time. - -::: - -## Add a Locale Dropdown - -To navigate seamlessly across languages, add a locale dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -module.exports = { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'localeDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The locale dropdown now appears in your navbar: - -![Locale Dropdown](./img/localeDropdown.png) - -## Build your localized site - -Build your site for a specific locale: - -```bash -npm run build -- --locale fr -``` - -Or build your site to include all the locales at once: - -```bash -npm run build -``` diff --git a/yellow-paper/docs/addresses-and-keys/0-keys-latex-preamble.md b/yellow-paper/docs/addresses-and-keys/0-keys-latex-preamble.md deleted file mode 100644 index c0a5816a5723..000000000000 --- a/yellow-paper/docs/addresses-and-keys/0-keys-latex-preamble.md +++ /dev/null @@ -1,90 +0,0 @@ -$$ - - -\gdef\sk{\color{red}{sk}\color{black}{}} -\gdef\seed{\color{red}\text{{seed}}\color{black}{}} - -\gdef\nskm{\color{red}{nsk_m}\color{black}{}} -\gdef\tskm{\color{red}{tsk_m}\color{black}{}} -\gdef\ivskm{\color{red}{ivsk_m}\color{black}{}} -\gdef\ovskm{\color{red}{ovsk_m}\color{black}{}} - -\gdef\Npkm{\color{green}{Npk_m}\color{black}{}} -\gdef\Tpkm{\color{green}{Tpk_m}\color{black}{}} -\gdef\Ivpkm{\color{green}{Ivpk_m}\color{black}{}} -\gdef\Ovpkm{\color{green}{Ovpk_m}\color{black}{}} - - -\gdef\address{\color{green}{address}\color{black}{}} -\gdef\codehash{\color{green}{code\_hash}\color{black}{}} -\gdef\constructorhash{\color{green}{constructor\_hash}\color{black}{}} -\gdef\classid{\color{green}{class\id}\color{black}{}} - - -\gdef\nskapp{\color{red}{nsk_{app}}\color{black}{}} -\gdef\tskapp{\color{red}{tsk_{app}}\color{black}{}} -\gdef\ivskapp{\color{red}{ivsk_{app}}\color{black}{}} -\gdef\ovskapp{\color{red}{ovsk_{app}}\color{black}{}} - -\gdef\Nkapp{\color{orange}{Nk_{app}}\color{black}{}} - -\gdef\Npkapp{\color{green}{Npk_{app}}\color{black}{}} - - -\gdef\Ivpkapp{\color{green}{Ivpk_{app}}\color{black}{}} - - -\gdef\happL{\color{green}{h_{app}^L}\color{black}{}} -\gdef\happn{\color{green}{h_{app}^n}\color{black}{}} -\gdef\happiv{\color{green}{h_{app}^{iv}}\color{black}{}} - - -\gdef\d{\color{green}{d}\color{black}{}} -\gdef\Gd{\color{green}{G_d}\color{black}{}} - -\gdef\Ivpkappd{\color{violet}{Ivpk_{app,d}}\color{black}{}} -\gdef\shareableIvpkappd{\color{violet}{\widetilde{Ivpk_{app,d}}}\color{black}{}} -\gdef\Ivpkmd{\color{violet}{Ivpk_{m,d}}\color{black}{}} -\gdef\shareableIvpkmd{\color{violet}{\widetilde{Ivpk_{m,d}}}\color{black}{}} - - -\gdef\ivskappstealth{\color{red}{ivsk_{app,stealth}}\color{black}{}} -\gdef\Ivpkappdstealth{\color{violet}{Ivpk_{app,d,stealth}}\color{black}{}} -\gdef\Pkappdstealth{\color{violet}{Pk_{app,d,stealth}}\color{black}{}} -\gdef\ivskmstealth{\color{red}{ivsk_{m,stealth}}\color{black}{}} -\gdef\Ivpkmdstealth{\color{violet}{Ivpk_{m,d,stealth}}\color{black}{}} -\gdef\Pkmdstealth{\color{violet}{Pk_{m,d,stealth}}\color{black}{}} - -\gdef\hstealth{\color{violet}{h_{stealth}}\color{black}{}} - - -\gdef\esk{\color{red}{esk}\color{black}{}} -\gdef\Epk{\color{green}{Epk}\color{black}{}} -\gdef\Epkd{\color{green}{Epk_d}\color{black}{}} -\gdef\eskheader{\color{red}{esk_{header}}\color{black}{}} -\gdef\Epkheader{\color{green}{Epk_{header}}\color{black}{}} -\gdef\Epkdheader{\color{green}{Epk_{d,header}}\color{black}{}} - -\gdef\sharedsecret{\color{violet}{\text{S}}\color{black}{}} -\gdef\sharedsecretmheader{\color{violet}{\text{S_{m,header}}}\color{black}{}} -\gdef\sharedsecretappheader{\color{violet}{\text{S_{app,header}}}\color{black}{}} - - -\gdef\hmencheader{\color{violet}{h_{m,enc,header}}\color{black}{}} -\gdef\happencheader{\color{violet}{h_{app,enc,header}}\color{black}{}} -\gdef\hmenc{\color{violet}{h_{m,enc}}\color{black}{}} -\gdef\happenc{\color{violet}{h_{app,enc}}\color{black}{}} -\gdef\incomingenckey{\color{violet}{h_{incoming\_enc\_key}}\color{black}{}} - - -\gdef\plaintext{\color{red}{\text{plaintext}}\color{black}{}} -\gdef\ciphertext{\color{green}{\text{ciphertext}}\color{black}{}} -\gdef\ciphertextheader{\color{green}{\text{ciphertext\_header}}\color{black}{}} -\gdef\payload{\color{green}{\text{payload}}\color{black}{}} - - -\gdef\tagg{\color{green}{\text{tag}}\color{black}{}} -\gdef\Taghs{\color{green}{\text{Tag}_{hs}}\color{black}{}} - - -$$ diff --git a/yellow-paper/docusaurus.config.js b/yellow-paper/docusaurus.config.js deleted file mode 100644 index 550b39ee385b..000000000000 --- a/yellow-paper/docusaurus.config.js +++ /dev/null @@ -1,154 +0,0 @@ -// @ts-check -// Note: type annotations allow type checking and IDEs autocompletion - -const lightCodeTheme = require("prism-react-renderer/themes/github"); -const darkCodeTheme = require("prism-react-renderer/themes/dracula"); -const math = require("remark-math"); -const katex = require("rehype-katex"); - -let macros = {}; - -/** @type {import('@docusaurus/types').Config} */ -const config = { - title: "Aztec Protocol Description", - tagline: "The Aztec Protocol, described.", - // favicon: "img/favicon.ico", - - // Set the production url of your site here - url: "https://your-docusaurus-test-site.com", - // Set the // pathname under which your site is served - // For GitHub pages deployment, it is often '//' - baseUrl: "/", - - // GitHub pages deployment config. - // If you aren't using GitHub pages, you don't need these. - organizationName: "AztecProtocol", // Usually your GitHub org/user name. - projectName: "aztec-packages", // Usually your repo name. - - onBrokenLinks: "throw", - onBrokenMarkdownLinks: "warn", - - // Even if you don't use internalization, you can use this field to set useful - // metadata like html lang. For example, if your site is Chinese, you may want - // to replace "en" with "zh-Hans". - i18n: { - defaultLocale: "en", - locales: ["en"], - }, - - markdown: { - mermaid: true, - }, - - themes: ["@docusaurus/theme-mermaid"], - - presets: [ - [ - "classic", - /** @type {import('@docusaurus/preset-classic').Options} */ - ({ - docs: { - sidebarPath: require.resolve("./sidebars.js"), - // Please change this to your repo. - // Remove this to remove the "edit this page" links. - editUrl: - "https://github.com/AztecProtocol/aztec-packages/edit/master/yellow-paper/docs/", - remarkPlugins: [math], - rehypePlugins: [ - [ - katex, - { - throwOnError: true, - globalGroup: true, - macros, - }, - ], - ], - }, - theme: { - customCss: require.resolve("./src/css/custom.css"), - }, - }), - ], - ], - - stylesheets: [ - { - href: "https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css", - type: "text/css", - integrity: - "sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM", - crossorigin: "anonymous", - }, - ], - - themeConfig: - /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ - ({ - algolia: { - appId: "6RXKCCZJK7", - apiKey: "aa09855dba35e5b48be3a126d7714170", - indexName: "yp-aztec", - }, - navbar: { - title: "Home", - // logo: { - // alt: "My Site Logo", - // src: "img/logo.svg", - // }, - items: [ - { - type: "docSidebar", - sidebarId: "yellowPaperSidebar", - position: "left", - label: "Protocol Description", - }, - { - href: "https://github.com/AztecProtocol/aztec-packages", - label: "GitHub", - position: "right", - }, - ], - }, - footer: { - style: "dark", - links: [ - { - title: "Docs", - items: [ - { - label: "Docs", - href: "https://docs.aztec.network", - }, - ], - }, - { - title: "Forum", - items: [ - { - label: "Forum", - href: "https://forum.aztec.network", - }, - ], - }, - { - title: "More", - items: [ - { - label: "GitHub", - href: "https://github.com/AztecProtocol/aztec-packages", - }, - ], - }, - ], - copyright: `Copyright © ${new Date().getFullYear()} Aztec Labs, Inc. Built with Docusaurus.`, - }, - - prism: { - theme: lightCodeTheme, - darkTheme: darkCodeTheme, - }, - }), -}; - -module.exports = config; diff --git a/yellow-paper/package.json b/yellow-paper/package.json deleted file mode 100644 index 5dc63509814c..000000000000 --- a/yellow-paper/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "classic", - "version": "0.0.0", - "private": true, - "scripts": { - "docusaurus": "docusaurus", - "start": "yarn preprocess && docusaurus start --host 0.0.0.0", - "start:dev": "yarn preprocess && docusaurus start --host 0.0.0.0", - "build": "docusaurus build", - "swizzle": "docusaurus swizzle", - "deploy": "docusaurus deploy", - "clear": "docusaurus clear", - "serve": "docusaurus serve", - "preprocess": "yarn node ./src/preprocess/index.js", - "write-translations": "docusaurus write-translations", - "write-heading-ids": "docusaurus write-heading-ids", - "typecheck": "tsc" - }, - "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/preset-classic": "2.4.3", - "@docusaurus/theme-mermaid": "^2.4.3", - "@mdx-js/react": "^1.6.22", - "clsx": "^1.2.1", - "prism-react-renderer": "^1.3.5", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-markdown": "6.0.0", - "rehype-katex": "5", - "remark-math": "3" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "2.4.3", - "@tsconfig/docusaurus": "^1.0.5", - "typescript": "^4.7.4" - }, - "browserslist": { - "production": [ - ">0.5%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "engines": { - "node": ">=16.14" - } -} diff --git a/yellow-paper/sidebars.js b/yellow-paper/sidebars.js deleted file mode 100644 index 72e5a35c7dfd..000000000000 --- a/yellow-paper/sidebars.js +++ /dev/null @@ -1,236 +0,0 @@ -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ - -// @ts-check - -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { - // By default, Docusaurus generates a sidebar from the docs folder structure - // tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], - - // But you can create a sidebar manually - - yellowPaperSidebar: [ - "intro", - { - label: "Cryptography", - type: "category", - link: { type: "doc", id: "cryptography/index" }, - items: [ - { - label: "Proving System", - type: "category", - link: { - type: "doc", - id: "cryptography/proving-system/performance-targets", - }, - items: [ - "cryptography/proving-system/performance-targets", - "cryptography/proving-system/overview", - "cryptography/proving-system/data-bus", - ], - }, - { - label: "Hashing", - type: "category", - link: { type: "doc", id: "cryptography/hashing/hashing" }, - items: [ - "cryptography/hashing/hashing", - "cryptography/hashing/poseidon2", - "cryptography/hashing/pedersen", - ], - }, - "cryptography/merkle-trees", - ], - }, - { - label: "Addresses & Keys", - type: "category", - link: { type: "doc", id: "addresses-and-keys/index" }, - items: [ - "addresses-and-keys/address", - "addresses-and-keys/keys-requirements", - "addresses-and-keys/keys", - { - label: "Example Usage of Keys", - type: "category", - items: [ - "addresses-and-keys/example-usage/nullifier", - "addresses-and-keys/example-usage/diversified-and-stealth-keys", - "addresses-and-keys/example-usage/tag-sequence-derivation", - "addresses-and-keys/example-usage/encrypt-and-tag", - ], - }, - "addresses-and-keys/precompiles", - "addresses-and-keys/diversified-and-stealth", - ], - }, - { - label: "State", - type: "category", - link: { type: "doc", id: "state/index" }, - items: [ - "state/tree-implementations", - "state/archive", - "state/note-hash-tree", - "state/nullifier-tree", - "state/public-data-tree", - ], - }, - { - label: "Transactions", - type: "category", - link: { type: "doc", id: "transactions/index" }, - items: [ - "transactions/local-execution", - "transactions/public-execution", - "transactions/tx-object", - "transactions/validity", - ], - }, - { - label: "Bytecode", - type: "category", - link: { type: "doc", id: "bytecode/index" }, - items: [], - }, - { - label: "Contract Deployment", - type: "category", - link: { type: "doc", id: "contract-deployment/index" }, - items: ["contract-deployment/classes", "contract-deployment/instances"], - }, - { - label: "Calls", - type: "category", - link: { type: "doc", id: "calls/index" }, - items: [ - "calls/sync-calls", - "calls/enqueued-calls", - "calls/batched-calls", - "calls/static-calls", - "calls/delegate-calls", - "calls/unconstrained-calls", - "calls/public-private-messaging", - ], - }, - { - label: "L1 smart contracts", - type: "category", - link: { type: "doc", id: "l1-smart-contracts/index" }, - items: ["l1-smart-contracts/frontier"], - }, - { - label: "Data availability", - type: "category", - link: { type: "doc", id: "data-publication-and-availability/index" }, - items: [ - "data-publication-and-availability/overview", - "data-publication-and-availability/published-data", - ], - }, - { - label: "Logs", - type: "category", - link: { type: "doc", id: "logs/index" }, - items: [], - }, - { - label: "Pre-compiled Contracts", - type: "category", - link: { type: "doc", id: "pre-compiled-contracts/index" }, - items: ["pre-compiled-contracts/registry"], - }, - { - label: "Private Message Delivery", - type: "category", - link: { type: "doc", id: "private-message-delivery/index" }, - items: [ - "private-message-delivery/private-msg-delivery", // renamed to avoid routing problems - "private-message-delivery/send-note-guidelines", - ], - }, - { - label: "Gas & Fees", - type: "category", - link: { type: "doc", id: "gas-and-fees/index" }, - items: [ - "gas-and-fees/fee-payments-and-metering", - "gas-and-fees/fee-schedule", - ], - }, - { - label: "Decentralization", - type: "category", - link: { type: "doc", id: "decentralization/governance" }, - items: [ - "decentralization/actors", - "decentralization/governance", - "decentralization/block-production", - "decentralization/p2p-network", - ], - }, - { - label: "Circuits", - type: "category", - link: { type: "doc", id: "circuits/high-level-topology" }, - items: [ - "circuits/private-function", - "circuits/private-kernel-initial", - "circuits/private-kernel-inner", - "circuits/private-kernel-reset", - "circuits/private-kernel-tail", - "circuits/public-kernel-initial", - "circuits/public-kernel-inner", - "circuits/public-kernel-tail", - ], - }, - { - label: "Rollup Circuits", - type: "category", - link: { type: "doc", id: "rollup-circuits/index" }, - items: [ - "rollup-circuits/base-rollup", - "rollup-circuits/merge-rollup", - "rollup-circuits/tree-parity", - "rollup-circuits/root-rollup", - ], - }, - { - label: "Aztec (Public) VM", - type: "category", - link: { type: "doc", id: "public-vm/index" }, - items: [ - "public-vm/intro", - "public-vm/state", - "public-vm/memory-model", - "public-vm/context", - "public-vm/execution", - "public-vm/nested-calls", - "public-vm/instruction-set", - { - label: "AVM Circuit", - type: "category", - link: { type: "doc", id: "public-vm/circuit-index" }, - items: [ - "public-vm/avm-circuit", - "public-vm/control-flow", - "public-vm/alu", - "public-vm/bytecode-validation-circuit", - ], - }, - "public-vm/type-structs", - ], - }, - ], -}; - -module.exports = sidebars; diff --git a/yellow-paper/src/components/HomepageFeatures/index.tsx b/yellow-paper/src/components/HomepageFeatures/index.tsx deleted file mode 100644 index 91ef4601d2fc..000000000000 --- a/yellow-paper/src/components/HomepageFeatures/index.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import React from 'react'; -import clsx from 'clsx'; -import styles from './styles.module.css'; - -type FeatureItem = { - title: string; - Svg: React.ComponentType>; - description: JSX.Element; -}; - -const FeatureList: FeatureItem[] = [ - { - title: 'Easy to Use', - Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, - description: ( - <> - Docusaurus was designed from the ground up to be easily installed and - used to get your website up and running quickly. - - ), - }, - { - title: 'Focus on What Matters', - Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, - description: ( - <> - Docusaurus lets you focus on your docs, and we'll do the chores. Go - ahead and move your docs into the docs directory. - - ), - }, - { - title: 'Powered by React', - Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, - description: ( - <> - Extend or customize your website layout by reusing React. Docusaurus can - be extended while reusing the same header and footer. - - ), - }, -]; - -function Feature({title, Svg, description}: FeatureItem) { - return ( -
-
- -
-
-

{title}

-

{description}

-
-
- ); -} - -export default function HomepageFeatures(): JSX.Element { - return ( -
-
-
- {FeatureList.map((props, idx) => ( - - ))} -
-
-
- ); -} diff --git a/yellow-paper/src/components/HomepageFeatures/styles.module.css b/yellow-paper/src/components/HomepageFeatures/styles.module.css deleted file mode 100644 index b248eb2e5dee..000000000000 --- a/yellow-paper/src/components/HomepageFeatures/styles.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureSvg { - height: 200px; - width: 200px; -} diff --git a/yellow-paper/src/css/custom.css b/yellow-paper/src/css/custom.css deleted file mode 100644 index 2bc6a4cfdef4..000000000000 --- a/yellow-paper/src/css/custom.css +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Any CSS included here will be global. The classic template - * bundles Infima by default. Infima is a CSS framework designed to - * work well for content-centric websites. - */ - -/* You can override the default Infima variables here. */ -:root { - --ifm-color-primary: #2e8555; - --ifm-color-primary-dark: #29784c; - --ifm-color-primary-darker: #277148; - --ifm-color-primary-darkest: #205d3b; - --ifm-color-primary-light: #33925d; - --ifm-color-primary-lighter: #359962; - --ifm-color-primary-lightest: #3cad6e; - --ifm-code-font-size: 95%; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); -} - -/* For readability concerns, you should choose a lighter palette in dark mode. */ -[data-theme='dark'] { - --ifm-color-primary: #25c2a0; - --ifm-color-primary-dark: #21af90; - --ifm-color-primary-darker: #1fa588; - --ifm-color-primary-darkest: #1a8870; - --ifm-color-primary-light: #29d5b0; - --ifm-color-primary-lighter: #32d8b4; - --ifm-color-primary-lightest: #4fddbf; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); -} diff --git a/yellow-paper/src/pages/index.module.css b/yellow-paper/src/pages/index.module.css deleted file mode 100644 index 9f71a5da775b..000000000000 --- a/yellow-paper/src/pages/index.module.css +++ /dev/null @@ -1,23 +0,0 @@ -/** - * CSS files with the .module.css suffix will be treated as CSS modules - * and scoped locally. - */ - -.heroBanner { - padding: 4rem 0; - text-align: center; - position: relative; - overflow: hidden; -} - -@media screen and (max-width: 996px) { - .heroBanner { - padding: 2rem; - } -} - -.buttons { - display: flex; - align-items: center; - justify-content: center; -} diff --git a/yellow-paper/src/pages/index.tsx b/yellow-paper/src/pages/index.tsx deleted file mode 100644 index f22d68a05c20..000000000000 --- a/yellow-paper/src/pages/index.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react'; -import clsx from 'clsx'; -import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import Layout from '@theme/Layout'; -import HomepageFeatures from '@site/src/components/HomepageFeatures'; - -import styles from './index.module.css'; - -function HomepageHeader() { - const {siteConfig} = useDocusaurusContext(); - return ( -
-
-

{siteConfig.title}

-

{siteConfig.tagline}

-
- - Read now - -
-
-
- ); -} - -export default function Home(): JSX.Element { - const {siteConfig} = useDocusaurusContext(); - return ( - - - - {/* TODO: put some pretty content in here: -
- -
*/} -
- ); -} diff --git a/yellow-paper/src/pages/markdown-page.md b/yellow-paper/src/pages/markdown-page.md deleted file mode 100644 index 9756c5b6685a..000000000000 --- a/yellow-paper/src/pages/markdown-page.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Markdown page example ---- - -# Markdown page example - -You don't need React to write simple standalone pages. diff --git a/yellow-paper/src/preprocess/InstructionSet/InstructionSet.js b/yellow-paper/src/preprocess/InstructionSet/InstructionSet.js deleted file mode 100644 index ac5def0355ee..000000000000 --- a/yellow-paper/src/preprocess/InstructionSet/InstructionSet.js +++ /dev/null @@ -1,1256 +0,0 @@ -const {instructionSize} = require('./InstructionSize'); - -const TOPICS_IN_TABLE = [ - "Name", "Summary", "Expression", -]; -const TOPICS_IN_SECTIONS = [ - "Name", "Summary", "Category", "Flags", "Args", "Expression", "Details", "World State access tracing", "Additional AVM circuit checks", "Triggers downstream circuit operations", "Tag checks", "Tag updates", "Bit-size", -]; - -const IN_TAG_DESCRIPTION = "The [tag/size](./memory-model#tags-and-tagged-memory) to check inputs against and tag the destination with."; -const IN_TAG_DESCRIPTION_NO_FIELD = IN_TAG_DESCRIPTION + " `field` type is NOT supported for this instruction."; -const DST_TAG_DESCRIPTION = "The [tag/size](./memory-model#tags-and-tagged-memory) to tag the destination with but not to check inputs against."; -const INDIRECT_FLAG_DESCRIPTION = "Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`."; - -const CALL_INSTRUCTION_ARGS = [ - {"name": "gasOffset", "description": "offset to three words containing `{l1GasLeft, l2GasLeft, daGasLeft}`: amount of gas to provide to the callee"}, - {"name": "addrOffset", "description": "address of the contract to call"}, - {"name": "argsOffset", "description": "memory offset to args (will become the callee's calldata)"}, - {"name": "argsSize", "description": "number of words to pass via callee's calldata", "mode": "immediate", "type": "u32"}, - {"name": "retOffset", "description": "destination memory offset specifying where to store the data returned from the callee"}, - {"name": "retSize", "description": "number of words to copy from data returned by callee", "mode": "immediate", "type": "u32"}, - {"name": "successOffset", "description": "destination memory offset specifying where to store the call's success (0: failure, 1: success)", "type": "u8"}, -]; -const CALL_INSTRUCTION_DETAILS = ` - ["Nested contract calls"](./nested-calls) provides a full explanation of this - instruction along with the shorthand used in the expression above. - The explanation includes details on charging gas for nested calls, - nested context derivation, world state tracing, and updating the parent context - after the nested call halts.`; - -const INSTRUCTION_SET_RAW = [ - { - "id": "add", - "Name": "`ADD`", - "Category": "Compute - Arithmetic", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] + M[bOffset] mod 2^k`", - "Summary": "Addition (a + b)", - "Details": "Wraps on overflow", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "sub", - "Name": "`SUB`", - "Category": "Compute - Arithmetic", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] - M[bOffset] mod 2^k`", - "Summary": "Subtraction (a - b)", - "Details": "Wraps on undeflow", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "mul", - "Name": "`MUL`", - "Category": "Compute - Arithmetic", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] * M[bOffset] mod 2^k`", - "Summary": "Multiplication (a * b)", - "Details": "Wraps on overflow", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "div", - "Name": "`DIV`", - "Category": "Compute - Arithmetic", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] / M[bOffset]`", - "Summary": "Unsigned integer division (a / b)", - "Details": "If the input is a field, it will be interpreted as an integer", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "fdiv", - "Name": "`FDIV`", - "Category": "Compute - Arithmetic", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] / M[bOffset]`", - "Summary": "Field division (a / b)", - "Details": "", - "Tag checks": "`T[aOffset] == T[bOffset] == field`", - "Tag updates": "`T[dstOffset] = field`", - }, - { - "id": "eq", - "Name": "`EQ`", - "Category": "Compute - Comparators", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result", "type": "u8"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] == M[bOffset] ? 1 : 0`", - "Summary": "Equality check (a == b)", - "Details": "", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = u8`", - }, - { - "id": "lt", - "Name": "`LT`", - "Category": "Compute - Comparators", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result", "type": "u8"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] < M[bOffset] ? 1 : 0`", - "Summary": "Less-than check (a < b)", - "Details": "", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = u8`", - }, - { - "id": "lte", - "Name": "`LTE`", - "Category": "Compute - Comparators", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result", "type": "u8"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] <= M[bOffset] ? 1 : 0`", - "Summary": "Less-than-or-equals check (a <= b)", - "Details": "", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = u8`", - }, - { - "id": "and", - "Name": "`AND`", - "Category": "Compute - Bitwise", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION_NO_FIELD}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] AND M[bOffset]`", - "Summary": "Bitwise AND (a & b)", - "Details": "", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "or", - "Name": "`OR`", - "Category": "Compute - Bitwise", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION_NO_FIELD}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] OR M[bOffset]`", - "Summary": "Bitwise OR (a | b)", - "Details": "", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "xor", - "Name": "`XOR`", - "Category": "Compute - Bitwise", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION_NO_FIELD}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] XOR M[bOffset]`", - "Summary": "Bitwise XOR (a ^ b)", - "Details": "", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "not", - "Name": "`NOT`", - "Category": "Compute - Bitwise", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION_NO_FIELD}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = NOT M[aOffset]`", - "Summary": "Bitwise NOT (inversion)", - "Details": "", - "Tag checks": "`T[aOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "shl", - "Name": "`SHL`", - "Category": "Compute - Bitwise", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION_NO_FIELD}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] << M[bOffset]`", - "Summary": "Bitwise leftward shift (a << b)", - "Details": "", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "shr", - "Name": "`SHR`", - "Category": "Compute - Bitwise", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": IN_TAG_DESCRIPTION_NO_FIELD}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of the operation's left input"}, - {"name": "bOffset", "description": "memory offset of the operation's right input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[aOffset] >> M[bOffset]`", - "Summary": "Bitwise rightward shift (a >> b)", - "Details": "", - "Tag checks": "`T[aOffset] == T[bOffset] == inTag`", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "cast", - "Name": "`CAST`", - "Category": "Type Conversions", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "dstTag", "description": DST_TAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of word to cast"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = cast(M[aOffset])`", - "Summary": "Type cast", - "Details": "Cast a word in memory based on the `dstTag` specified in the bytecode. Truncates (`M[dstOffset] = M[aOffset] mod 2^dstsize`) when casting to a smaller type, left-zero-pads when casting to a larger type. See [here](./memory-model#cast-and-tag-conversions) for more details.", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = dstTag`", - }, - { - "id": "address", - "Name": "`ADDRESS`", - "Category": "Execution Environment", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.address`", - "Summary": "Get the address of the currently executing l2 contract", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "storageaddress", - "Name": "`STORAGEADDRESS`", - "Category": "Execution Environment", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.storageAddress`", - "Summary": "Get the _storage_ address of the currently executing context", - "Details": "The storage address is used for public storage accesses.", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "origin", - "Name": "`ORIGIN`", - "Category": "Execution Environment", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.origin`", - "Summary": "Get the transaction's origination address", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "sender", - "Name": "`SENDER`", - "Category": "Execution Environment", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.sender`", - "Summary": "Get the address of the sender (caller of the current context)", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "portal", - "Name": "`PORTAL`", - "Category": "Execution Environment", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.portal`", - "Summary": "Get the address of the l1 portal contract", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "feeperl1gas", - "Name": "`FEEPERL1GAS`", - "Category": "Execution Environment", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.feePerL1Gas`", - "Summary": "Get the fee to be paid per \"L1 gas\" - constant for entire transaction", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "feeperl2gas", - "Name": "`FEEPERL2GAS`", - "Category": "Execution Environment", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.feePerL2Gas`", - "Summary": "Get the fee to be paid per \"L2 gas\" - constant for entire transaction", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "feeperdagas", - "Name": "`FEEPERDAGAS`", - "Category": "Execution Environment", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.feePerDaGas`", - "Summary": "Get the fee to be paid per \"DA gas\" - constant for entire transaction", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "contractcalldepth", - "Name": "`CONTRACTCALLDEPTH`", - "Category": "Execution Environment", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.contractCallDepth`", - "Summary": "Get how many contract calls deep the current call context is", - "Details": "Note: security issues with EVM's tx.origin can be resolved by asserting `calldepth == 0`.", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u8`", - }, - { - "id": "chainid", - "Name": "`CHAINID`", - "Category": "Execution Environment - Globals", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.globals.chainId`", - "Summary": "Get this rollup's L1 chain ID", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "version", - "Name": "`VERSION`", - "Category": "Execution Environment - Globals", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.globals.version`", - "Summary": "Get this rollup's L2 version ID", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "blocknumber", - "Name": "`BLOCKNUMBER`", - "Category": "Execution Environment - Globals", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.globals.blocknumber`", - "Summary": "Get this L2 block's number", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "timestamp", - "Name": "`TIMESTAMP`", - "Category": "Execution Environment - Globals", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.globals.timestamp`", - "Summary": "Get this L2 block's timestamp", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u64`", - }, - { - "id": "coinbase", - "Name": "`COINBASE`", - "Category": "Execution Environment - Globals", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.globals.coinbase`", - "Summary": "Get the block's beneficiary address", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "blockl1gaslimit", - "Name": "`BLOCKL1GASLIMIT`", - "Category": "Execution Environment - Globals", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.globals.l1GasLimit`", - "Summary": "Total amount of \"L1 gas\" that a block can consume", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "blockl2gaslimit", - "Name": "`BLOCKL2GASLIMIT`", - "Category": "Execution Environment - Globals", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.globals.l2GasLimit`", - "Summary": "Total amount of \"L2 gas\" that a block can consume", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "blockdagaslimit", - "Name": "`BLOCKDAGASLIMIT`", - "Category": "Execution Environment - Globals", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.environment.globals.daGasLimit`", - "Summary": "Total amount of \"DA gas\" that a block can consume", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "calldatacopy", - "Name": "`CALLDATACOPY`", - "Category": "Execution Environment - Calldata", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "cdOffset", "description": "offset into calldata to copy from"}, - {"name": "copySize", "description": "number of words to copy", "mode": "immediate", "type": "u32"}, - {"name": "dstOffset", "description": "memory offset specifying where to copy the first word to"}, - ], - "Expression": "`M[dstOffset:dstOffset+copySize] = context.environment.calldata[cdOffset:cdOffset+copySize]`", - "Summary": "Copy calldata into memory", - "Details": "Calldata is read-only and cannot be directly operated on by other instructions. This instruction moves words from calldata into memory so they can be operated on normally.", - "Tag checks": "", - "Tag updates": "`T[dstOffset:dstOffset+copySize] = field`", - }, - { - "id": "l1gasleft", - "Name": "`L1GASLEFT`", - "Category": "Machine State - Gas", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.machineState.l1GasLeft`", - "Summary": "Remaining \"L1 gas\" for this call (after this instruction)", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "l2gasleft", - "Name": "`L2GASLEFT`", - "Category": "Machine State - Gas", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.MachineState.l2GasLeft`", - "Summary": "Remaining \"L2 gas\" for this call (after this instruction)", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "dagasleft", - "Name": "`DAGASLEFT`", - "Category": "Machine State - Gas", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = context.machineState.daGasLeft`", - "Summary": "Remaining \"DA gas\" for this call (after this instruction)", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = u32`", - }, - { - "id": "jump", - "Name": "`JUMP`", - "Category": "Machine State - Control Flow", - "Flags": [], - "Args": [ - {"name": "loc", "description": "target location to jump to", "mode": "immediate", "type": "u32"}, - ], - "Expression": "`context.machineState.pc = loc`", - "Summary": "Jump to a location in the bytecode", - "Details": "Target location is an immediate value (a constant in the bytecode).", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "jumpi", - "Name": "`JUMPI`", - "Category": "Machine State - Control Flow", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "loc", "description": "target location conditionally jump to", "mode": "immediate", "type": "u32"}, - {"name": "condOffset", "description": "memory offset of the operations 'conditional' input"}, - ], - "Expression": "`context.machineState.pc = M[condOffset] > 0 ? loc : context.machineState.pc`", - "Summary": "Conditionally jump to a location in the bytecode", - "Details": "Target location is an immediate value (a constant in the bytecode). `T[condOffset]` is not checked because the greater-than-zero suboperation is the same regardless of type.", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "internalcall", - "Name": "`INTERNALCALL`", - "Category": "Machine State - Control Flow", - "Flags": [], - "Args": [ - {"name": "loc", "description": "target location to jump/call to", "mode": "immediate", "type": "u32"}, - ], - "Expression": ` -context.machineState.internalCallStack.push(context.machineState.pc) -context.machineState.pc = loc -`, - "Summary": "Make an internal call. Push the current PC to the internal call stack and jump to the target location.", - "Details": "Target location is an immediate value (a constant in the bytecode).", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "internalreturn", - "Name": "`INTERNALRETURN`", - "Category": "Machine State - Control Flow", - "Flags": [], - "Args": [], - "Expression": "`context.machineState.pc = context.machineState.internalCallStack.pop()`", - "Summary": "Return from an internal call. Pop from the internal call stack and jump to the popped location.", - "Details": "", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "set", - "Name": "`SET`", - "Category": "Machine State - Memory", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - {"name": "inTag", "description": "The [type/size](./memory-model#tags-and-tagged-memory) to check inputs against and tag the destination with. `field` type is NOT supported for SET."}, - ], - "Args": [ - {"name": "const", "description": "an N-bit constant value from the bytecode to store in memory (any type except `field`)", "mode": "immediate"}, - {"name": "dstOffset", "description": "memory offset specifying where to store the constant"}, - ], - "Expression": "`M[dstOffset] = const`", - "Summary": "Set a memory word from a constant in the bytecode", - "Details": "Set memory word at `dstOffset` to `const`'s immediate value. `const`'s bit-size (N) can be 8, 16, 32, 64, or 128 based on `inTag`. It _cannot be 254 (`field` type)_!", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = inTag`", - }, - { - "id": "mov", - "Name": "`MOV`", - "Category": "Machine State - Memory", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "srcOffset", "description": "memory offset of word to move"}, - {"name": "dstOffset", "description": "memory offset specifying where to store that word"}, - ], - "Expression": "`M[dstOffset] = M[srcOffset]`", - "Summary": "Move a word from source memory location to destination", - "Details": "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = T[srcOffset]`", - }, - { - "id": "cmov", - "Name": "`CMOV`", - "Category": "Machine State - Memory", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "aOffset", "description": "memory offset of word 'a' to conditionally move"}, - {"name": "bOffset", "description": "memory offset of word 'b' to conditionally move"}, - {"name": "condOffset", "description": "memory offset of the operations 'conditional' input"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": "`M[dstOffset] = M[condOffset] > 0 ? M[aOffset] : M[bOffset]`", - "Summary": "Move a word (conditionally chosen) from one memory location to another (`d = cond > 0 ? a : b`)", - "Details": "One of two source memory locations is chosen based on the condition. `T[condOffset]` is not checked because the greater-than-zero suboperation is the same regardless of type.", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = M[condOffset] > 0 ? T[aOffset] : T[bOffset]`", - }, - { - "id": "sload", - "Name": "`SLOAD`", - "Category": "World State - Public Storage", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "slotOffset", "description": "memory offset of the storage slot to load from"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, - ], - "Expression": ` -M[dstOffset] = S[M[slotOffset]] -`, - "Summary": "Load a word from this contract's persistent public storage. Zero is loaded for unwritten slots.", - "Details": ` -// Expression is shorthand for -leafIndex = hash(context.environment.storageAddress, M[slotOffset]) -exists = context.worldState.publicStorage.has(leafIndex) // exists == previously-written -if exists: - value = context.worldState.publicStorage.get(leafIndex: leafIndex) -else: - value = 0 -M[dstOffset] = value -`, - "World State access tracing": ` -context.worldStateAccessTrace.publicStorageReads.append( - TracedStorageRead { - callPointer: context.environment.callPointer, - slot: M[slotOffset], - exists: exists, // defined above - value: value, // defined above - counter: ++context.worldStateAccessTrace.accessCounter, - } -) -`, - "Triggers downstream circuit operations": "Storage slot siloing (hash with contract address), public data tree membership check", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = field`", - }, - { - "id": "sstore", - "Name": "`SSTORE`", - "Category": "World State - Public Storage", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "srcOffset", "description": "memory offset of the word to store"}, - {"name": "slotOffset", "description": "memory offset containing the storage slot to store to"}, - ], - "Expression": ` -S[M[slotOffset]] = M[srcOffset] -`, - "Summary": "Write a word to this contract's persistent public storage", - "Details": ` -// Expression is shorthand for -context.worldState.publicStorage.set({ - leafIndex: hash(context.environment.storageAddress, M[slotOffset]), - leaf: M[srcOffset], -}) -`, - "World State access tracing": ` -context.worldStateAccessTrace.publicStorageWrites.append( - TracedStorageWrite { - callPointer: context.environment.callPointer, - slot: M[slotOffset], - value: M[srcOffset], - counter: ++context.worldStateAccessTrace.accessCounter, - } -) -`, - "Triggers downstream circuit operations": "Storage slot siloing (hash with contract address), public data tree update", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "notehashexists", - "Name": "`NOTEHASHEXISTS`", - "Category": "World State - Notes & Nullifiers", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "noteHashOffset", "description": "memory offset of the note hash"}, - {"name": "leafIndexOffset", "description": "memory offset of the leaf index"}, - {"name": "existsOffset", "description": "memory offset specifying where to store operation's result (whether the note hash leaf exists)"}, - ], - "Expression": ` -exists = context.worldState.noteHashes.has({ - leafIndex: M[leafIndexOffset] - leaf: hash(context.environment.storageAddress, M[noteHashOffset]), -}) -M[existsOffset] = exists -`, - "Summary": "Check whether a note hash exists in the note hash tree (as of the start of the current block)", - "World State access tracing": ` -context.worldStateAccessTrace.noteHashChecks.append( - TracedNoteHashCheck { - callPointer: context.environment.callPointer, - leafIndex: M[leafIndexOffset] - noteHash: M[noteHashOffset], - exists: exists, // defined above - counter: ++context.worldStateAccessTrace.accessCounter, - } -) -`, - "Triggers downstream circuit operations": "Note hash siloing (hash with storage contract address), note hash tree membership check", - "Tag checks": "", - "Tag updates": "`T[existsOffset] = u8`", - }, - { - "id": "emitnotehash", - "Name": "`EMITNOTEHASH`", - "Category": "World State - Notes & Nullifiers", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "noteHashOffset", "description": "memory offset of the note hash"}, - ], - "Expression": ` -context.worldState.noteHashes.append( - hash(context.environment.storageAddress, M[noteHashOffset]) -) -`, - "Summary": "Emit a new note hash to be inserted into the note hash tree", - "World State access tracing": ` -context.worldStateAccessTrace.newNoteHashes.append( - TracedNoteHash { - callPointer: context.environment.callPointer, - noteHash: M[noteHashOffset], // unsiloed note hash - counter: ++context.worldStateAccessTrace.accessCounter, - } -) -`, - "Triggers downstream circuit operations": "Note hash siloing (hash with contract address), note hash tree insertion.", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "nullifierexists", - "Name": "`NULLIFIEREXISTS`", - "Category": "World State - Notes & Nullifiers", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "nullifierOffset", "description": "memory offset of the unsiloed nullifier"}, - {"name": "addressOffset", "description": "memory offset of the storage address"}, - {"name": "existsOffset", "description": "memory offset specifying where to store operation's result (whether the nullifier exists)"}, - ], - "Expression": ` -exists = pendingNullifiers.has(M[addressOffset], M[nullifierOffset]) || context.worldState.nullifiers.has( - hash(M[addressOffset], M[nullifierOffset]) -) -M[existsOffset] = exists -`, - "Summary": "Check whether a nullifier exists in the nullifier tree (including nullifiers from earlier in the current transaction or from earlier in the current block)", - "World State access tracing": ` -context.worldStateAccessTrace.nullifierChecks.append( - TracedNullifierCheck { - callPointer: context.environment.callPointer, - nullifier: M[nullifierOffset], - storageAddress: M[addressOffset], - exists: exists, // defined above - counter: ++context.worldStateAccessTrace.accessCounter, - } -) -`, - "Triggers downstream circuit operations": "Nullifier siloing (hash with storage contract address), nullifier tree membership check", - "Tag checks": "", - "Tag updates": "`T[existsOffset] = u8`", - }, - { - "id": "emitnullifier", - "Name": "`EMITNULLIFIER`", - "Category": "World State - Notes & Nullifiers", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "nullifierOffset", "description": "memory offset of nullifier"}, - ], - "Expression": ` -context.worldState.nullifiers.append( - hash(context.environment.storageAddress, M[nullifierOffset]) -) -`, - "Summary": "Emit a new nullifier to be inserted into the nullifier tree", - "World State access tracing": ` -context.worldStateAccessTrace.newNullifiers.append( - TracedNullifier { - callPointer: context.environment.callPointer, - nullifier: M[nullifierOffset], // unsiloed nullifier - counter: ++context.worldStateAccessTrace.accessCounter, - } -) -`, - "Triggers downstream circuit operations": "Nullifier siloing (hash with contract address), nullifier tree non-membership-check and insertion.", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "l1tol2msgexists", - "Name": "`L1TOL2MSGEXISTS`", - "Category": "World State - Messaging", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "msgHashOffset", "description": "memory offset of the message hash"}, - {"name": "msgLeafIndexOffset", "description": "memory offset of the message's leaf index in the L1-to-L2 message tree"}, - {"name": "existsOffset", "description": "memory offset specifying where to store operation's result (whether the message exists in the L1-to-L2 message tree)"}, - ], - "Expression": ` -exists = context.worldState.l1ToL2Messages.has({ - leafIndex: M[msgLeafIndexOffset], leaf: M[msgHashOffset] -}) -M[existsOffset] = exists -`, - "Summary": "Check if a message exists in the L1-to-L2 message tree", - "World State access tracing": ` -context.worldStateAccessTrace.l1ToL2MessagesChecks.append( - L1ToL2Message { - callPointer: context.environment.callPointer, - leafIndex: M[msgLeafIndexOffset], - msgHash: M[msgHashOffset], - exists: exists, // defined above - } -) -`, - "Triggers downstream circuit operations": "L1-to-L2 message tree membership check", - "Tag checks": "", - "Tag updates": ` -T[existsOffset] = u8, -`, - }, - { - "id": "headermember", - "Name": "`HEADERMEMBER`", - "Category": "World State - Archive Tree & Headers", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "blockIndexOffset", "description": "memory offset of the block index (same as archive tree leaf index) of the header to access"}, - {"name": "memberIndexOffset", "description": "memory offset of the index of the member to retrieve from the header of the specified block"}, - {"name": "existsOffset", "description": "memory offset specifying where to store operation's result (whether the leaf exists in the archive tree)"}, - {"name": "dstOffset", "description": "memory offset specifying where to store operation's result (the retrieved header member)"}, - ], - "Expression": ` -exists = context.worldState.header.has({ - leafIndex: M[blockIndexOffset], leaf: M[msgKeyOffset] -}) -M[existsOffset] = exists -if exists: - header = context.worldState.headers.get(M[blockIndexOffset]) - M[dstOffset] = header[M[memberIndexOffset]] // member -`, - "Summary": "Check if a header exists in the [archive tree](../state/archive) and retrieve the specified member if so", - "World State access tracing": ` -context.worldStateAccessTrace.archiveChecks.append( - TracedArchiveLeafCheck { - leafIndex: M[blockIndexOffset], // leafIndex == blockIndex - leaf: exists ? hash(header) : 0, // "exists" defined above - } -) -`, - "Additional AVM circuit checks": "Hashes entire header to archive leaf for tracing. Aggregates header accesses and so that a header need only be hashed once.", - "Triggers downstream circuit operations": "Archive tree membership check", - "Tag checks": "", - "Tag updates": ` -T[existsOffset] = u8 -T[dstOffset] = field -`, - }, - { - "id": "getcontractinstance", - "Name": "`GETCONTRACTINSTANCE`", - "Category": "Other", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "addressOffset", "description": "memory offset of the contract instance address"}, - {"name": "dstOffset", "description": "location to write the contract instance information to"}, - ], - "Expression": ` -M[dstOffset:dstOffset+CONTRACT_INSTANCE_SIZE+1] = [ - instance_found_in_address, - instance.salt ?? 0, - instance.deployer ?? 0, - instance.contractClassId ?? 0, - instance.initializationHash ?? 0, - instance.portalContractAddress ?? 0, - instance.publicKeysHash ?? 0, -] -`, - "Summary": "Copies contract instance data to memory", - "Tag checks": "", - "Tag updates": "T[dstOffset:dstOffset+CONTRACT_INSTANCE_SIZE+1] = field", - "Additional AVM circuit checks": "TO-DO", - "Triggers downstream circuit operations": "TO-DO", - }, - { - "id": "emitunencryptedlog", - "Name": "`EMITUNENCRYPTEDLOG`", - "Category": "Accrued Substate - Logging", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "eventSelectorOffset", "description": "memory offset of the event selector"}, - {"name": "logOffset", "description": "memory offset of the data to log"}, - {"name": "logSize", "description": "number of words to log", "mode": "immediate", "type": "u32"}, - ], - "Expression": ` -context.accruedSubstate.unencryptedLogs.append( - UnencryptedLog { - address: context.environment.address, - eventSelector: M[eventSelectorOffset], - log: M[logOffset:logOffset+logSize], - } -) -`, - "Summary": "Emit an unencrypted log", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "sendl2tol1msg", - "Name": "`SENDL2TOL1MSG`", - "Category": "Accrued Substate - Messaging", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "recipientOffset", "description": "memory offset of the message recipient"}, - {"name": "contentOffset", "description": "memory offset of the message content"}, - ], - "Expression": ` -context.accruedSubstate.sentL2ToL1Messages.append( - SentL2ToL1Message { - address: context.environment.address, - recipient: M[recipientOffset], - message: M[contentOffset] - } -) -`, - "Summary": "Send an L2-to-L1 message", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "call", - "Name": "`CALL`", - "Category": "Control Flow - Contract Calls", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": CALL_INSTRUCTION_ARGS, - "Expression":` -// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } -chargeGas(context, - l1GasCost=M[instr.args.gasOffset], - l2GasCost=M[instr.args.gasOffset+1], - daGasCost=M[instr.args.gasOffset+2]) -traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=false) -execute(nestedContext) -updateContextAfterNestedCall(context, instr.args, nestedContext) -`, - "Summary": "Call into another contract", - "Details": `Creates a new (nested) execution context and triggers execution within that context. - Execution proceeds in the nested context until it reaches a halt at which point - execution resumes in the current/calling context. - A non-existent contract or one with no code will return success. ` - + CALL_INSTRUCTION_DETAILS, - "Tag checks": "`T[gasOffset] == T[gasOffset+1] == T[gasOffset+2] == u32`", - "Tag updates": ` -T[successOffset] = u8 -T[retOffset:retOffset+retSize] = field -`, - }, - { - "id": "staticcall", - "Name": "`STATICCALL`", - "Category": "Control Flow - Contract Calls", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": CALL_INSTRUCTION_ARGS, - "Expression": ` -// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } -chargeGas(context, - l1GasCost=M[instr.args.gasOffset], - l2GasCost=M[instr.args.gasOffset+1], - daGasCost=M[instr.args.gasOffset+2]) -traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=true, isDelegateCall=false) -execute(nestedContext) -updateContextAfterNestedCall(context, instr.args, nestedContext) -`, - "Summary": "Call into another contract, disallowing World State and Accrued Substate modifications", - "Details": `Same as \`CALL\`, but disallows World State and Accrued Substate modifications. ` - + CALL_INSTRUCTION_DETAILS, - "Tag checks": "`T[gasOffset] == T[gasOffset+1] == T[gasOffset+2] == u32`", - "Tag updates": ` -T[successOffset] = u8 -T[retOffset:retOffset+retSize] = field -`, - }, - { - "id": "delegatecall", - "Name": "`DELEGATECALL`", - "Category": "Control Flow - Contract Calls", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": CALL_INSTRUCTION_ARGS, - "Expression": ` -// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } -chargeGas(context, - l1GasCost=M[instr.args.gasOffset], - l2GasCost=M[instr.args.gasOffset+1], - daGasCost=M[instr.args.gasOffset+2]) -traceNestedCall(context, instr.args.addrOffset) -nestedContext = deriveContext(context, instr.args, isStaticCall=false, isDelegateCall=true) -execute(nestedContext) -updateContextAfterNestedCall(context, instr.args, nestedContext) -`, - "Summary": "Call into another contract, but keep the caller's `sender` and `storageAddress`", - "Details": `Same as \`CALL\`, but \`sender\` and \`storageAddress\` remains - the same in the nested call as they were in the caller. ` - + CALL_INSTRUCTION_DETAILS, - "Tag checks": "`T[gasOffset] == T[gasOffset+1] == T[gasOffset+2] == u32`", - "Tag updates": ` -T[successOffset] = u8 -T[retOffset:retOffset+retSize] = field -`, - }, - { - "id": "return", - "Name": "`RETURN`", - "Category": "Control Flow - Contract Calls", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "retOffset", "description": "memory offset of first word to return"}, - {"name": "retSize", "description": "number of words to return", "mode": "immediate", "type": "u32"}, - ], - "Expression": ` -context.contractCallResults.output = M[retOffset:retOffset+retSize] -halt -`, - "Summary": "Halt execution within this context (without revert), optionally returning some data", - "Details": "Return control flow to the calling context/contract. Caller will accept World State and Accrued Substate modifications. See [\"Halting\"](./execution#halting) to learn more. See [\"Nested contract calls\"](./nested-calls) to see how the caller updates its context after the nested call halts.", - "Tag checks": "", - "Tag updates": "", - }, - { - "id": "revert", - "Name": "`REVERT`", - "Category": "Control Flow - Contract Calls", - "Flags": [ - {"name": "indirect", "description": INDIRECT_FLAG_DESCRIPTION}, - ], - "Args": [ - {"name": "retOffset", "description": "memory offset of first word to return"}, - {"name": "retSize", "description": "number of words to return", "mode": "immediate", "type": "u32"}, - ], - "Expression": ` -context.contractCallResults.output = M[retOffset:retOffset+retSize] -context.contractCallResults.reverted = true -halt -`, - "Summary": "Halt execution within this context as `reverted`, optionally returning some data", - "Details": "Return control flow to the calling context/contract. Caller will reject World State and Accrued Substate modifications. See [\"Halting\"](./execution#halting) to learn more. See [\"Nested contract calls\"](./nested-calls) to see how the caller updates its context after the nested call halts.", - "Tag checks": "", - "Tag updates": "", - }, -]; -const INSTRUCTION_SET = INSTRUCTION_SET_RAW.map((instr) => {instr['Bit-size'] = instructionSize(instr); return instr;}); - -module.exports = { - TOPICS_IN_TABLE, - TOPICS_IN_SECTIONS, - INSTRUCTION_SET, -}; diff --git a/yellow-paper/src/preprocess/InstructionSet/genMarkdown.js b/yellow-paper/src/preprocess/InstructionSet/genMarkdown.js deleted file mode 100644 index 4070fdc76a58..000000000000 --- a/yellow-paper/src/preprocess/InstructionSet/genMarkdown.js +++ /dev/null @@ -1,139 +0,0 @@ -const fs = require("fs"); -const path = require("path"); - -const { - TOPICS_IN_TABLE, - TOPICS_IN_SECTIONS, - INSTRUCTION_SET, - instructionSize -} = require('./InstructionSet'); - -function escapeBraces(str) { - return str.replace(//g, ">"); -} - -function stripBraces(str) { - return str.replace(/[<>]/g, ''); -} - -function instructionSetPreface() { - let preface = "[comment]: # (THIS IS A GENERATED FILE! DO NOT EDIT!)\n"; - preface += "[comment]: # (Generated via `yarn preprocess`)\n\n"; - preface += "[comment]: # (Generated by genMarkdown.js, InstructionSet.js, InstructionSize.js)\n\n"; - preface += "import Markdown from 'react-markdown'\n"; - preface += "import CodeBlock from '@theme/CodeBlock'\n\n"; - return preface; -} - -function toOpcode(index) { - return '0x' + index.toString(16).padStart(2, '0'); -} - -function htmlInstructionSetTable() { - let table = "## Instructions Table\n"; - table += "\nClick on an instruction name to jump to its section.\n"; - table += "\n\n"; - let header = ""; - for (let t = 0; t < TOPICS_IN_TABLE.length; t++) { - header += ``; - } - table += `${header}\n`; - - for (let i = 0; i < INSTRUCTION_SET.length; i++) { - const instr = INSTRUCTION_SET[i]; - const name = instr['Name']; - let row = `\n`; - row += `\t`; - row += `\t`; - - for (let t = 0; t < TOPICS_IN_TABLE.length; t++) { - const topic = TOPICS_IN_TABLE[t]; - - if (topic == 'Name') continue; // skip - let cell = instr[topic]; - if (cell[0] == '\n') { // if string starts with newline, assume it's a multi-line code block - cell = `\n{\`${cell.trim()}\`}\n\t`; - } else if (cell[0] == '`' && topic != 'Name') { - cell = `{\n\t\t\`${cell.replace(/`/g, '')}\`\n\t}`; - } else { - cell = escapeBraces(cell); // escape html - cell = `${cell}`; - } - row += `\n\t`; - } - row += "\n"; - table += `${row}\n`; - } - table += "
Opcode${TOPICS_IN_TABLE[t]}
${toOpcode(i)}[${stripBraces(name)}](#isa-section-${instr['id']})${cell}
\n"; - return table; -} - -function markdownSublist(items) { - let markdown = ""; - for (let i = 0; i < items.length; i++) { - let item = items[i]; - if (typeof item === 'string') { - markdown += `\n\t- ${item}`; - } else { - markdown += `\n\t- **${item['name']}**: ${item['description']}`; - } - } - return markdown; -} - -function markdownInstructionSetSection(pathToGenDir) { - let markdown = "## Instructions\n"; - for (let i = 0; i < INSTRUCTION_SET.length; i++) { - const instr = INSTRUCTION_SET[i]; - const name = instr['Name']; - let subsection = `###
${name}\n`; - subsection += `${instr['Summary']}\n\n`; - subsection += `[See in table.](#isa-table-${instr['id']})\n\n`; - subsection += `- **Opcode**: ${toOpcode(i)}\n`; - for (let t = 0; t < TOPICS_IN_SECTIONS.length; t++) { - const topic = TOPICS_IN_SECTIONS[t]; - let field = instr[topic]; - if (topic == 'Name' || topic == 'Summary' || !field || field.length == 0) continue; // skip - - let item = `- **${topic}**: ` - if (Array.isArray(field) ) { - item += markdownSublist(field); - } else if (field[0] == '\n') { // if string starts with newline, assume it's a multi-line code block - item += `\n\n{\`${field.trim()}\`}\n`; - } else { - item += field; - } - subsection += `${item}\n`; - } - const bitFormatPath = `./images/bit-formats/${name.replace(/`/g, '')}.png`; - if (fs.existsSync(`${pathToGenDir}/${bitFormatPath}`)) { - subsection += `\n[![](${bitFormatPath})](${bitFormatPath})`; - } - markdown += `\n${subsection}\n`; - } - return markdown; -} - -async function generateInstructionSet() { - const rootDir = path.join(__dirname, "../../../"); - const docsDir = path.join(rootDir, "docs", "docs"); - - const relPath = path.relative(docsDir, "docs/public-vm/gen/_instruction-set.mdx"); - const docsFilePath = path.resolve(docsDir, relPath); - const docsDirName = path.dirname(docsFilePath); - if (!fs.existsSync(docsDirName)) { - fs.mkdirSync(docsDirName, { recursive: true }); - } - - const preface = instructionSetPreface(); - const table = htmlInstructionSetTable(); - const section = markdownInstructionSetSection(docsDirName); - const doc = `${preface}\n${table}\n\n${section}`; - fs.writeFileSync(docsFilePath, doc); - - console.log("Preprocessing complete."); -} - -module.exports = { - generateInstructionSet, -}; \ No newline at end of file diff --git a/yellow-paper/src/preprocess/index.js b/yellow-paper/src/preprocess/index.js deleted file mode 100644 index fe2167bdf096..000000000000 --- a/yellow-paper/src/preprocess/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const {generateInstructionSet} = require('./InstructionSet/genMarkdown'); - -async function run() { - await generateInstructionSet(); -} -run(); \ No newline at end of file diff --git a/yellow-paper/static/.nojekyll b/yellow-paper/static/.nojekyll deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/yellow-paper/static/img/DO_NOT_USE.txt b/yellow-paper/static/img/DO_NOT_USE.txt deleted file mode 100644 index 2e8a4a837c15..000000000000 --- a/yellow-paper/static/img/DO_NOT_USE.txt +++ /dev/null @@ -1 +0,0 @@ -Instead, pics will be auto-pasted into an `images` subdir of any doc that you paste an image into. \ No newline at end of file diff --git a/yellow-paper/static/img/docusaurus-social-card.jpg b/yellow-paper/static/img/docusaurus-social-card.jpg deleted file mode 100644 index ffcb448210e1..000000000000 Binary files a/yellow-paper/static/img/docusaurus-social-card.jpg and /dev/null differ diff --git a/yellow-paper/static/img/docusaurus.png b/yellow-paper/static/img/docusaurus.png deleted file mode 100644 index f458149e3c8f..000000000000 Binary files a/yellow-paper/static/img/docusaurus.png and /dev/null differ diff --git a/yellow-paper/static/img/favicon.ico b/yellow-paper/static/img/favicon.ico deleted file mode 100644 index c01d54bcd39a..000000000000 Binary files a/yellow-paper/static/img/favicon.ico and /dev/null differ diff --git a/yellow-paper/static/img/logo.svg b/yellow-paper/static/img/logo.svg deleted file mode 100644 index 9db6d0d066e3..000000000000 --- a/yellow-paper/static/img/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/yellow-paper/static/img/undraw_docusaurus_mountain.svg b/yellow-paper/static/img/undraw_docusaurus_mountain.svg deleted file mode 100644 index af961c49a888..000000000000 --- a/yellow-paper/static/img/undraw_docusaurus_mountain.svg +++ /dev/null @@ -1,171 +0,0 @@ - - Easy to Use - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/yellow-paper/static/img/undraw_docusaurus_react.svg b/yellow-paper/static/img/undraw_docusaurus_react.svg deleted file mode 100644 index 94b5cf08f88f..000000000000 --- a/yellow-paper/static/img/undraw_docusaurus_react.svg +++ /dev/null @@ -1,170 +0,0 @@ - - Powered by React - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/yellow-paper/static/img/undraw_docusaurus_tree.svg b/yellow-paper/static/img/undraw_docusaurus_tree.svg deleted file mode 100644 index d9161d33920c..000000000000 --- a/yellow-paper/static/img/undraw_docusaurus_tree.svg +++ /dev/null @@ -1,40 +0,0 @@ - - Focus on What Matters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/yellow-paper/tsconfig.json b/yellow-paper/tsconfig.json deleted file mode 100644 index 6f4756980d4d..000000000000 --- a/yellow-paper/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // This file is not used in compilation. It is here just for a nice editor experience. - "extends": "@tsconfig/docusaurus/tsconfig.json", - "compilerOptions": { - "baseUrl": "." - } -} diff --git a/yellow-paper/yarn.lock b/yellow-paper/yarn.lock deleted file mode 100644 index 7e3c4614e878..000000000000 --- a/yellow-paper/yarn.lock +++ /dev/null @@ -1,8277 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@algolia/autocomplete-core@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7" - integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw== - dependencies: - "@algolia/autocomplete-plugin-algolia-insights" "1.9.3" - "@algolia/autocomplete-shared" "1.9.3" - -"@algolia/autocomplete-plugin-algolia-insights@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz#9b7f8641052c8ead6d66c1623d444cbe19dde587" - integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg== - dependencies: - "@algolia/autocomplete-shared" "1.9.3" - -"@algolia/autocomplete-preset-algolia@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz#64cca4a4304cfcad2cf730e83067e0c1b2f485da" - integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA== - dependencies: - "@algolia/autocomplete-shared" "1.9.3" - -"@algolia/autocomplete-shared@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa" - integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ== - -"@algolia/cache-browser-local-storage@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.20.0.tgz#357318242fc542ffce41d6eb5b4a9b402921b0bb" - integrity sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ== - dependencies: - "@algolia/cache-common" "4.20.0" - -"@algolia/cache-common@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.20.0.tgz#ec52230509fce891091ffd0d890618bcdc2fa20d" - integrity sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ== - -"@algolia/cache-in-memory@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.20.0.tgz#5f18d057bd6b3b075022df085c4f83bcca4e3e67" - integrity sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg== - dependencies: - "@algolia/cache-common" "4.20.0" - -"@algolia/client-account@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.20.0.tgz#23ce0b4cffd63100fb7c1aa1c67a4494de5bd645" - integrity sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q== - dependencies: - "@algolia/client-common" "4.20.0" - "@algolia/client-search" "4.20.0" - "@algolia/transporter" "4.20.0" - -"@algolia/client-analytics@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.20.0.tgz#0aa6bef35d3a41ac3991b3f46fcd0bf00d276fa9" - integrity sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug== - dependencies: - "@algolia/client-common" "4.20.0" - "@algolia/client-search" "4.20.0" - "@algolia/requester-common" "4.20.0" - "@algolia/transporter" "4.20.0" - -"@algolia/client-common@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.20.0.tgz#ca60f04466515548651c4371a742fbb8971790ef" - integrity sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ== - dependencies: - "@algolia/requester-common" "4.20.0" - "@algolia/transporter" "4.20.0" - -"@algolia/client-personalization@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.20.0.tgz#ca81308e8ad0db3b27458b78355f124f29657181" - integrity sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ== - dependencies: - "@algolia/client-common" "4.20.0" - "@algolia/requester-common" "4.20.0" - "@algolia/transporter" "4.20.0" - -"@algolia/client-search@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.20.0.tgz#3bcce817ca6caedc835e0eaf6f580e02ee7c3e15" - integrity sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg== - dependencies: - "@algolia/client-common" "4.20.0" - "@algolia/requester-common" "4.20.0" - "@algolia/transporter" "4.20.0" - -"@algolia/events@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950" - integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ== - -"@algolia/logger-common@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.20.0.tgz#f148ddf67e5d733a06213bebf7117cb8a651ab36" - integrity sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ== - -"@algolia/logger-console@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.20.0.tgz#ac443d27c4e94357f3063e675039cef0aa2de0a7" - integrity sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA== - dependencies: - "@algolia/logger-common" "4.20.0" - -"@algolia/requester-browser-xhr@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.20.0.tgz#db16d0bdef018b93b51681d3f1e134aca4f64814" - integrity sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw== - dependencies: - "@algolia/requester-common" "4.20.0" - -"@algolia/requester-common@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.20.0.tgz#65694b2263a8712b4360fef18680528ffd435b5c" - integrity sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng== - -"@algolia/requester-node-http@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.20.0.tgz#b52b182b52b0b16dec4070832267d484a6b1d5bb" - integrity sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng== - dependencies: - "@algolia/requester-common" "4.20.0" - -"@algolia/transporter@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.20.0.tgz#7e5b24333d7cc9a926b2f6a249f87c2889b944a9" - integrity sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg== - dependencies: - "@algolia/cache-common" "4.20.0" - "@algolia/logger-common" "4.20.0" - "@algolia/requester-common" "4.20.0" - -"@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.8.3": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== - dependencies: - "@babel/highlight" "^7.22.13" - chalk "^2.4.2" - -"@babel/compat-data@^7.22.20", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.20.tgz#8df6e96661209623f1975d66c35ffca66f3306d0" - integrity sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw== - -"@babel/core@7.12.9": - version "7.12.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" - integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.5" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.5" - "@babel/parser" "^7.12.7" - "@babel/template" "^7.12.7" - "@babel/traverse" "^7.12.9" - "@babel/types" "^7.12.7" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/core@^7.18.6", "@babel/core@^7.19.6": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.0.tgz#f8259ae0e52a123eb40f552551e647b506a94d83" - integrity sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helpers" "^7.23.0" - "@babel/parser" "^7.23.0" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.0" - "@babel/types" "^7.23.0" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/generator@^7.12.5", "@babel/generator@^7.18.7", "@babel/generator@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" - integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== - dependencies: - "@babel/types" "^7.23.0" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/helper-annotate-as-pure@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" - integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" - integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== - dependencies: - "@babel/types" "^7.22.15" - -"@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" - integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== - dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-validator-option" "^7.22.15" - browserslist "^4.21.9" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" - integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-member-expression-to-functions" "^7.22.15" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - semver "^6.3.1" - -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" - integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - regexpu-core "^5.3.1" - semver "^6.3.1" - -"@babel/helper-define-polyfill-provider@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz#82c825cadeeeee7aad237618ebbe8fa1710015d7" - integrity sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw== - dependencies: - "@babel/helper-compilation-targets" "^7.22.6" - "@babel/helper-plugin-utils" "^7.22.5" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - -"@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" - integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== - -"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" - integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/types" "^7.23.0" - -"@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-member-expression-to-functions@^7.22.15": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" - integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== - dependencies: - "@babel/types" "^7.23.0" - -"@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" - integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== - dependencies: - "@babel/types" "^7.22.15" - -"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" - integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.20" - -"@babel/helper-optimise-call-expression@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" - integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-plugin-utils@7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" - integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== - -"@babel/helper-remap-async-to-generator@^7.22.5", "@babel/helper-remap-async-to-generator@^7.22.9": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" - integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-wrap-function" "^7.22.20" - -"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" - integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-member-expression-to-functions" "^7.22.15" - "@babel/helper-optimise-call-expression" "^7.22.5" - -"@babel/helper-simple-access@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" - integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" - integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-split-export-declaration@^7.22.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== - -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - -"@babel/helper-validator-option@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" - integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== - -"@babel/helper-wrap-function@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" - integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== - dependencies: - "@babel/helper-function-name" "^7.22.5" - "@babel/template" "^7.22.15" - "@babel/types" "^7.22.19" - -"@babel/helpers@^7.12.5", "@babel/helpers@^7.23.0": - version "7.23.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.1.tgz#44e981e8ce2b9e99f8f0b703f3326a4636c16d15" - integrity sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA== - dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.0" - "@babel/types" "^7.23.0" - -"@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.12.7", "@babel/parser@^7.18.8", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" - integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz#02dc8a03f613ed5fdc29fb2f728397c78146c962" - integrity sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz#2aeb91d337d4e1a1e7ce85b76a37f5301781200f" - integrity sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.22.15" - -"@babel/plugin-proposal-object-rest-spread@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" - integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.1" - -"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": - version "7.21.0-placeholder-for-preset-env.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" - integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-import-assertions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" - integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-import-attributes@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" - integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-import-meta@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" - integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-jsx@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" - integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-top-level-await@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" - integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" - integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-arrow-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" - integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-async-generator-functions@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.15.tgz#3b153af4a6b779f340d5b80d3f634f55820aefa3" - integrity sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w== - dependencies: - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-transform-async-to-generator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" - integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== - dependencies: - "@babel/helper-module-imports" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.5" - -"@babel/plugin-transform-block-scoped-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" - integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-block-scoping@^7.22.15": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz#8744d02c6c264d82e1a4bc5d2d501fd8aff6f022" - integrity sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-class-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" - integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-class-static-block@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz#dc8cc6e498f55692ac6b4b89e56d87cec766c974" - integrity sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.11" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-transform-classes@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz#aaf4753aee262a232bbc95451b4bdf9599c65a0b" - integrity sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.9" - "@babel/helper-split-export-declaration" "^7.22.6" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" - integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/template" "^7.22.5" - -"@babel/plugin-transform-destructuring@^7.22.15": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz#6447aa686be48b32eaf65a73e0e2c0bd010a266c" - integrity sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-dotall-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" - integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-duplicate-keys@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" - integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-dynamic-import@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz#2c7722d2a5c01839eaf31518c6ff96d408e447aa" - integrity sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-transform-exponentiation-operator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" - integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-export-namespace-from@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz#b3c84c8f19880b6c7440108f8929caf6056db26c" - integrity sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-transform-for-of@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz#f64b4ccc3a4f131a996388fae7680b472b306b29" - integrity sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-function-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" - integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== - dependencies: - "@babel/helper-compilation-targets" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-json-strings@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz#689a34e1eed1928a40954e37f74509f48af67835" - integrity sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-transform-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" - integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-logical-assignment-operators@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz#24c522a61688bde045b7d9bc3c2597a4d948fc9c" - integrity sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-transform-member-expression-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" - integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-modules-amd@^7.22.5": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz#05b2bc43373faa6d30ca89214731f76f966f3b88" - integrity sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw== - dependencies: - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-modules-commonjs@^7.22.15", "@babel/plugin-transform-modules-commonjs@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz#b3dba4757133b2762c00f4f94590cf6d52602481" - integrity sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ== - dependencies: - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-simple-access" "^7.22.5" - -"@babel/plugin-transform-modules-systemjs@^7.22.11": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz#77591e126f3ff4132a40595a6cccd00a6b60d160" - integrity sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg== - dependencies: - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - -"@babel/plugin-transform-modules-umd@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" - integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== - dependencies: - "@babel/helper-module-transforms" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" - integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-new-target@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" - integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz#debef6c8ba795f5ac67cd861a81b744c5d38d9fc" - integrity sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-transform-numeric-separator@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz#498d77dc45a6c6db74bb829c02a01c1d719cbfbd" - integrity sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-transform-object-rest-spread@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz#21a95db166be59b91cde48775310c0df6e1da56f" - integrity sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q== - dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.22.15" - -"@babel/plugin-transform-object-super@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" - integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.5" - -"@babel/plugin-transform-optional-catch-binding@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz#461cc4f578a127bb055527b3e77404cad38c08e0" - integrity sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-transform-optional-chaining@^7.22.15": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz#73ff5fc1cf98f542f09f29c0631647d8ad0be158" - integrity sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz#719ca82a01d177af358df64a514d64c2e3edb114" - integrity sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-private-methods@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" - integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-private-property-in-object@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz#ad45c4fc440e9cb84c718ed0906d96cf40f9a4e1" - integrity sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.11" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-transform-property-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" - integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-react-constant-elements@^7.18.12": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.22.5.tgz#6dfa7c1c37f7d7279e417ceddf5a04abb8bb9c29" - integrity sha512-BF5SXoO+nX3h5OhlN78XbbDrBOffv+AxPP2ENaJOVqjWCgBDeOY3WcaUcddutGSfoap+5NEQ/q/4I3WZIvgkXA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-react-display-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz#3c4326f9fce31c7968d6cb9debcaf32d9e279a2b" - integrity sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-react-jsx-development@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87" - integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.22.5" - -"@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz#7e6266d88705d7c49f11c98db8b9464531289cd6" - integrity sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-jsx" "^7.22.5" - "@babel/types" "^7.22.15" - -"@babel/plugin-transform-react-pure-annotations@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz#1f58363eef6626d6fa517b95ac66fe94685e32c0" - integrity sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-regenerator@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" - integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - regenerator-transform "^0.15.2" - -"@babel/plugin-transform-reserved-words@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" - integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-runtime@^7.18.6": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.15.tgz#3a625c4c05a39e932d7d34f5d4895cdd0172fdc9" - integrity sha512-tEVLhk8NRZSmwQ0DJtxxhTrCht1HVo8VaMzYT4w6lwyKBuHsgoioAUA7/6eT2fRfc5/23fuGdlwIxXhRVgWr4g== - dependencies: - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - babel-plugin-polyfill-corejs2 "^0.4.5" - babel-plugin-polyfill-corejs3 "^0.8.3" - babel-plugin-polyfill-regenerator "^0.5.2" - semver "^6.3.1" - -"@babel/plugin-transform-shorthand-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" - integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-spread@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" - integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - -"@babel/plugin-transform-sticky-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" - integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-template-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" - integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-typeof-symbol@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" - integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-typescript@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz#15adef906451d86349eb4b8764865c960eb54127" - integrity sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-typescript" "^7.22.5" - -"@babel/plugin-transform-unicode-escapes@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" - integrity sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-unicode-property-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" - integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-unicode-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" - integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-unicode-sets-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" - integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/preset-env@^7.18.6", "@babel/preset-env@^7.19.4": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.20.tgz#de9e9b57e1127ce0a2f580831717f7fb677ceedb" - integrity sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg== - dependencies: - "@babel/compat-data" "^7.22.20" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.15" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.15" - "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.22.5" - "@babel/plugin-syntax-import-attributes" "^7.22.5" - "@babel/plugin-syntax-import-meta" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.22.5" - "@babel/plugin-transform-async-generator-functions" "^7.22.15" - "@babel/plugin-transform-async-to-generator" "^7.22.5" - "@babel/plugin-transform-block-scoped-functions" "^7.22.5" - "@babel/plugin-transform-block-scoping" "^7.22.15" - "@babel/plugin-transform-class-properties" "^7.22.5" - "@babel/plugin-transform-class-static-block" "^7.22.11" - "@babel/plugin-transform-classes" "^7.22.15" - "@babel/plugin-transform-computed-properties" "^7.22.5" - "@babel/plugin-transform-destructuring" "^7.22.15" - "@babel/plugin-transform-dotall-regex" "^7.22.5" - "@babel/plugin-transform-duplicate-keys" "^7.22.5" - "@babel/plugin-transform-dynamic-import" "^7.22.11" - "@babel/plugin-transform-exponentiation-operator" "^7.22.5" - "@babel/plugin-transform-export-namespace-from" "^7.22.11" - "@babel/plugin-transform-for-of" "^7.22.15" - "@babel/plugin-transform-function-name" "^7.22.5" - "@babel/plugin-transform-json-strings" "^7.22.11" - "@babel/plugin-transform-literals" "^7.22.5" - "@babel/plugin-transform-logical-assignment-operators" "^7.22.11" - "@babel/plugin-transform-member-expression-literals" "^7.22.5" - "@babel/plugin-transform-modules-amd" "^7.22.5" - "@babel/plugin-transform-modules-commonjs" "^7.22.15" - "@babel/plugin-transform-modules-systemjs" "^7.22.11" - "@babel/plugin-transform-modules-umd" "^7.22.5" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" - "@babel/plugin-transform-new-target" "^7.22.5" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" - "@babel/plugin-transform-numeric-separator" "^7.22.11" - "@babel/plugin-transform-object-rest-spread" "^7.22.15" - "@babel/plugin-transform-object-super" "^7.22.5" - "@babel/plugin-transform-optional-catch-binding" "^7.22.11" - "@babel/plugin-transform-optional-chaining" "^7.22.15" - "@babel/plugin-transform-parameters" "^7.22.15" - "@babel/plugin-transform-private-methods" "^7.22.5" - "@babel/plugin-transform-private-property-in-object" "^7.22.11" - "@babel/plugin-transform-property-literals" "^7.22.5" - "@babel/plugin-transform-regenerator" "^7.22.10" - "@babel/plugin-transform-reserved-words" "^7.22.5" - "@babel/plugin-transform-shorthand-properties" "^7.22.5" - "@babel/plugin-transform-spread" "^7.22.5" - "@babel/plugin-transform-sticky-regex" "^7.22.5" - "@babel/plugin-transform-template-literals" "^7.22.5" - "@babel/plugin-transform-typeof-symbol" "^7.22.5" - "@babel/plugin-transform-unicode-escapes" "^7.22.10" - "@babel/plugin-transform-unicode-property-regex" "^7.22.5" - "@babel/plugin-transform-unicode-regex" "^7.22.5" - "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" - "@babel/preset-modules" "0.1.6-no-external-plugins" - "@babel/types" "^7.22.19" - babel-plugin-polyfill-corejs2 "^0.4.5" - babel-plugin-polyfill-corejs3 "^0.8.3" - babel-plugin-polyfill-regenerator "^0.5.2" - core-js-compat "^3.31.0" - semver "^6.3.1" - -"@babel/preset-modules@0.1.6-no-external-plugins": - version "0.1.6-no-external-plugins" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" - integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/preset-react@^7.18.6": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.22.15.tgz#9a776892b648e13cc8ca2edf5ed1264eea6b6afc" - integrity sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-transform-react-display-name" "^7.22.5" - "@babel/plugin-transform-react-jsx" "^7.22.15" - "@babel/plugin-transform-react-jsx-development" "^7.22.5" - "@babel/plugin-transform-react-pure-annotations" "^7.22.5" - -"@babel/preset-typescript@^7.18.6": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.0.tgz#cc6602d13e7e5b2087c811912b87cf937a9129d9" - integrity sha512-6P6VVa/NM/VlAYj5s2Aq/gdVg8FSENCg3wlZ6Qau9AcPaoF5LbN1nyGlR9DTRIw9PpxI94e+ReydsJHcjwAweg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-syntax-jsx" "^7.22.5" - "@babel/plugin-transform-modules-commonjs" "^7.23.0" - "@babel/plugin-transform-typescript" "^7.22.15" - -"@babel/regjsgen@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" - integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== - -"@babel/runtime-corejs3@^7.18.6": - version "7.23.1" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.23.1.tgz#d03f5819f4ba81a21dd1f80edfb19983e9e20fc1" - integrity sha512-OKKfytwoc0tr7cDHwQm0RLVR3y+hDGFz3EPuvLNU/0fOeXJeKNIHj7ffNVFnncWt3sC58uyUCRSzf8nBQbyF6A== - dependencies: - core-js-pure "^3.30.2" - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.13", "@babel/runtime@^7.8.4": - version "7.23.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.1.tgz#72741dc4d413338a91dcb044a86f3c0bc402646d" - integrity sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/template@^7.12.7", "@babel/template@^7.22.15", "@babel/template@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" - -"@babel/traverse@^7.12.9", "@babel/traverse@^7.18.8", "@babel/traverse@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.0.tgz#18196ddfbcf4ccea324b7f6d3ada00d8c5a99c53" - integrity sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.0" - "@babel/types" "^7.23.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.12.7", "@babel/types@^7.20.0", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.4.4": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" - integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== - dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@braintree/sanitize-url@^6.0.0": - version "6.0.4" - resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz#923ca57e173c6b232bbbb07347b1be982f03e783" - integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A== - -"@colors/colors@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" - integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== - -"@discoveryjs/json-ext@0.5.7": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" - integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== - -"@docsearch/css@3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.5.2.tgz#610f47b48814ca94041df969d9fcc47b91fc5aac" - integrity sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA== - -"@docsearch/react@^3.1.1": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.5.2.tgz#2e6bbee00eb67333b64906352734da6aef1232b9" - integrity sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng== - dependencies: - "@algolia/autocomplete-core" "1.9.3" - "@algolia/autocomplete-preset-algolia" "1.9.3" - "@docsearch/css" "3.5.2" - algoliasearch "^4.19.1" - -"@docusaurus/core@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-2.4.3.tgz#d86624901386fd8164ce4bff9cc7f16fde57f523" - integrity sha512-dWH5P7cgeNSIg9ufReX6gaCl/TmrGKD38Orbwuz05WPhAQtFXHd5B8Qym1TiXfvUNvwoYKkAJOJuGe8ou0Z7PA== - dependencies: - "@babel/core" "^7.18.6" - "@babel/generator" "^7.18.7" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-runtime" "^7.18.6" - "@babel/preset-env" "^7.18.6" - "@babel/preset-react" "^7.18.6" - "@babel/preset-typescript" "^7.18.6" - "@babel/runtime" "^7.18.6" - "@babel/runtime-corejs3" "^7.18.6" - "@babel/traverse" "^7.18.8" - "@docusaurus/cssnano-preset" "2.4.3" - "@docusaurus/logger" "2.4.3" - "@docusaurus/mdx-loader" "2.4.3" - "@docusaurus/react-loadable" "5.5.2" - "@docusaurus/utils" "2.4.3" - "@docusaurus/utils-common" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - "@slorber/static-site-generator-webpack-plugin" "^4.0.7" - "@svgr/webpack" "^6.2.1" - autoprefixer "^10.4.7" - babel-loader "^8.2.5" - babel-plugin-dynamic-import-node "^2.3.3" - boxen "^6.2.1" - chalk "^4.1.2" - chokidar "^3.5.3" - clean-css "^5.3.0" - cli-table3 "^0.6.2" - combine-promises "^1.1.0" - commander "^5.1.0" - copy-webpack-plugin "^11.0.0" - core-js "^3.23.3" - css-loader "^6.7.1" - css-minimizer-webpack-plugin "^4.0.0" - cssnano "^5.1.12" - del "^6.1.1" - detect-port "^1.3.0" - escape-html "^1.0.3" - eta "^2.0.0" - file-loader "^6.2.0" - fs-extra "^10.1.0" - html-minifier-terser "^6.1.0" - html-tags "^3.2.0" - html-webpack-plugin "^5.5.0" - import-fresh "^3.3.0" - leven "^3.1.0" - lodash "^4.17.21" - mini-css-extract-plugin "^2.6.1" - postcss "^8.4.14" - postcss-loader "^7.0.0" - prompts "^2.4.2" - react-dev-utils "^12.0.1" - react-helmet-async "^1.3.0" - react-loadable "npm:@docusaurus/react-loadable@5.5.2" - react-loadable-ssr-addon-v5-slorber "^1.0.1" - react-router "^5.3.3" - react-router-config "^5.1.1" - react-router-dom "^5.3.3" - rtl-detect "^1.0.4" - semver "^7.3.7" - serve-handler "^6.1.3" - shelljs "^0.8.5" - terser-webpack-plugin "^5.3.3" - tslib "^2.4.0" - update-notifier "^5.1.0" - url-loader "^4.1.1" - wait-on "^6.0.1" - webpack "^5.73.0" - webpack-bundle-analyzer "^4.5.0" - webpack-dev-server "^4.9.3" - webpack-merge "^5.8.0" - webpackbar "^5.0.2" - -"@docusaurus/cssnano-preset@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.3.tgz#1d7e833c41ce240fcc2812a2ac27f7b862f32de0" - integrity sha512-ZvGSRCi7z9wLnZrXNPG6DmVPHdKGd8dIn9pYbEOFiYihfv4uDR3UtxogmKf+rT8ZlKFf5Lqne8E8nt08zNM8CA== - dependencies: - cssnano-preset-advanced "^5.3.8" - postcss "^8.4.14" - postcss-sort-media-queries "^4.2.1" - tslib "^2.4.0" - -"@docusaurus/logger@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-2.4.3.tgz#518bbc965fb4ebe8f1d0b14e5f4161607552d34c" - integrity sha512-Zxws7r3yLufk9xM1zq9ged0YHs65mlRmtsobnFkdZTxWXdTYlWWLWdKyNKAsVC+D7zg+pv2fGbyabdOnyZOM3w== - dependencies: - chalk "^4.1.2" - tslib "^2.4.0" - -"@docusaurus/mdx-loader@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-2.4.3.tgz#e8ff37f30a060eaa97b8121c135f74cb531a4a3e" - integrity sha512-b1+fDnWtl3GiqkL0BRjYtc94FZrcDDBV1j8446+4tptB9BAOlePwG2p/pK6vGvfL53lkOsszXMghr2g67M0vCw== - dependencies: - "@babel/parser" "^7.18.8" - "@babel/traverse" "^7.18.8" - "@docusaurus/logger" "2.4.3" - "@docusaurus/utils" "2.4.3" - "@mdx-js/mdx" "^1.6.22" - escape-html "^1.0.3" - file-loader "^6.2.0" - fs-extra "^10.1.0" - image-size "^1.0.1" - mdast-util-to-string "^2.0.0" - remark-emoji "^2.2.0" - stringify-object "^3.3.0" - tslib "^2.4.0" - unified "^9.2.2" - unist-util-visit "^2.0.3" - url-loader "^4.1.1" - webpack "^5.73.0" - -"@docusaurus/module-type-aliases@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-2.4.3.tgz#d08ef67e4151e02f352a2836bcf9ecde3b9c56ac" - integrity sha512-cwkBkt1UCiduuvEAo7XZY01dJfRn7UR/75mBgOdb1hKknhrabJZ8YH+7savd/y9kLExPyrhe0QwdS9GuzsRRIA== - dependencies: - "@docusaurus/react-loadable" "5.5.2" - "@docusaurus/types" "2.4.3" - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-router-config" "*" - "@types/react-router-dom" "*" - react-helmet-async "*" - react-loadable "npm:@docusaurus/react-loadable@5.5.2" - -"@docusaurus/plugin-content-blog@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.3.tgz#6473b974acab98e967414d8bbb0d37e0cedcea14" - integrity sha512-PVhypqaA0t98zVDpOeTqWUTvRqCEjJubtfFUQ7zJNYdbYTbS/E/ytq6zbLVsN/dImvemtO/5JQgjLxsh8XLo8Q== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/logger" "2.4.3" - "@docusaurus/mdx-loader" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils" "2.4.3" - "@docusaurus/utils-common" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - cheerio "^1.0.0-rc.12" - feed "^4.2.2" - fs-extra "^10.1.0" - lodash "^4.17.21" - reading-time "^1.5.0" - tslib "^2.4.0" - unist-util-visit "^2.0.3" - utility-types "^3.10.0" - webpack "^5.73.0" - -"@docusaurus/plugin-content-docs@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.4.3.tgz#aa224c0512351e81807adf778ca59fd9cd136973" - integrity sha512-N7Po2LSH6UejQhzTCsvuX5NOzlC+HiXOVvofnEPj0WhMu1etpLEXE6a4aTxrtg95lQ5kf0xUIdjX9sh3d3G76A== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/logger" "2.4.3" - "@docusaurus/mdx-loader" "2.4.3" - "@docusaurus/module-type-aliases" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - "@types/react-router-config" "^5.0.6" - combine-promises "^1.1.0" - fs-extra "^10.1.0" - import-fresh "^3.3.0" - js-yaml "^4.1.0" - lodash "^4.17.21" - tslib "^2.4.0" - utility-types "^3.10.0" - webpack "^5.73.0" - -"@docusaurus/plugin-content-pages@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.4.3.tgz#7f285e718b53da8c8d0101e70840c75b9c0a1ac0" - integrity sha512-txtDVz7y3zGk67q0HjG0gRttVPodkHqE0bpJ+7dOaTH40CQFLSh7+aBeGnPOTl+oCPG+hxkim4SndqPqXjQ8Bg== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/mdx-loader" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - fs-extra "^10.1.0" - tslib "^2.4.0" - webpack "^5.73.0" - -"@docusaurus/plugin-debug@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-2.4.3.tgz#2f90eb0c9286a9f225444e3a88315676fe02c245" - integrity sha512-LkUbuq3zCmINlFb+gAd4ZvYr+bPAzMC0hwND4F7V9bZ852dCX8YoWyovVUBKq4er1XsOwSQaHmNGtObtn8Av8Q== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils" "2.4.3" - fs-extra "^10.1.0" - react-json-view "^1.21.3" - tslib "^2.4.0" - -"@docusaurus/plugin-google-analytics@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.4.3.tgz#0d19993136ade6f7a7741251b4f617400d92ab45" - integrity sha512-KzBV3k8lDkWOhg/oYGxlK5o9bOwX7KpPc/FTWoB+SfKhlHfhq7qcQdMi1elAaVEIop8tgK6gD1E58Q+XC6otSQ== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - tslib "^2.4.0" - -"@docusaurus/plugin-google-gtag@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.4.3.tgz#e1a80b0696771b488562e5b60eff21c9932d9e1c" - integrity sha512-5FMg0rT7sDy4i9AGsvJC71MQrqQZwgLNdDetLEGDHLfSHLvJhQbTCUGbGXknUgWXQJckcV/AILYeJy+HhxeIFA== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - tslib "^2.4.0" - -"@docusaurus/plugin-google-tag-manager@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-2.4.3.tgz#e41fbf79b0ffc2de1cc4013eb77798cff0ad98e3" - integrity sha512-1jTzp71yDGuQiX9Bi0pVp3alArV0LSnHXempvQTxwCGAEzUWWaBg4d8pocAlTpbP9aULQQqhgzrs8hgTRPOM0A== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - tslib "^2.4.0" - -"@docusaurus/plugin-sitemap@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.4.3.tgz#1b3930900a8f89670ce7e8f83fb4730cd3298c32" - integrity sha512-LRQYrK1oH1rNfr4YvWBmRzTL0LN9UAPxBbghgeFRBm5yloF6P+zv1tm2pe2hQTX/QP5bSKdnajCvfnScgKXMZQ== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/logger" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils" "2.4.3" - "@docusaurus/utils-common" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - fs-extra "^10.1.0" - sitemap "^7.1.1" - tslib "^2.4.0" - -"@docusaurus/preset-classic@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-2.4.3.tgz#074c57ebf29fa43d23bd1c8ce691226f542bc262" - integrity sha512-tRyMliepY11Ym6hB1rAFSNGwQDpmszvWYJvlK1E+md4SW8i6ylNHtpZjaYFff9Mdk3i/Pg8ItQq9P0daOJAvQw== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/plugin-content-blog" "2.4.3" - "@docusaurus/plugin-content-docs" "2.4.3" - "@docusaurus/plugin-content-pages" "2.4.3" - "@docusaurus/plugin-debug" "2.4.3" - "@docusaurus/plugin-google-analytics" "2.4.3" - "@docusaurus/plugin-google-gtag" "2.4.3" - "@docusaurus/plugin-google-tag-manager" "2.4.3" - "@docusaurus/plugin-sitemap" "2.4.3" - "@docusaurus/theme-classic" "2.4.3" - "@docusaurus/theme-common" "2.4.3" - "@docusaurus/theme-search-algolia" "2.4.3" - "@docusaurus/types" "2.4.3" - -"@docusaurus/react-loadable@5.5.2", "react-loadable@npm:@docusaurus/react-loadable@5.5.2": - version "5.5.2" - resolved "https://registry.yarnpkg.com/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz#81aae0db81ecafbdaee3651f12804580868fa6ce" - integrity sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ== - dependencies: - "@types/react" "*" - prop-types "^15.6.2" - -"@docusaurus/theme-classic@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-2.4.3.tgz#29360f2eb03a0e1686eb19668633ef313970ee8f" - integrity sha512-QKRAJPSGPfDY2yCiPMIVyr+MqwZCIV2lxNzqbyUW0YkrlmdzzP3WuQJPMGLCjWgQp/5c9kpWMvMxjhpZx1R32Q== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/mdx-loader" "2.4.3" - "@docusaurus/module-type-aliases" "2.4.3" - "@docusaurus/plugin-content-blog" "2.4.3" - "@docusaurus/plugin-content-docs" "2.4.3" - "@docusaurus/plugin-content-pages" "2.4.3" - "@docusaurus/theme-common" "2.4.3" - "@docusaurus/theme-translations" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils" "2.4.3" - "@docusaurus/utils-common" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - "@mdx-js/react" "^1.6.22" - clsx "^1.2.1" - copy-text-to-clipboard "^3.0.1" - infima "0.2.0-alpha.43" - lodash "^4.17.21" - nprogress "^0.2.0" - postcss "^8.4.14" - prism-react-renderer "^1.3.5" - prismjs "^1.28.0" - react-router-dom "^5.3.3" - rtlcss "^3.5.0" - tslib "^2.4.0" - utility-types "^3.10.0" - -"@docusaurus/theme-common@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-2.4.3.tgz#bb31d70b6b67d0bdef9baa343192dcec49946a2e" - integrity sha512-7KaDJBXKBVGXw5WOVt84FtN8czGWhM0lbyWEZXGp8AFfL6sZQfRTluFp4QriR97qwzSyOfQb+nzcDZZU4tezUw== - dependencies: - "@docusaurus/mdx-loader" "2.4.3" - "@docusaurus/module-type-aliases" "2.4.3" - "@docusaurus/plugin-content-blog" "2.4.3" - "@docusaurus/plugin-content-docs" "2.4.3" - "@docusaurus/plugin-content-pages" "2.4.3" - "@docusaurus/utils" "2.4.3" - "@docusaurus/utils-common" "2.4.3" - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-router-config" "*" - clsx "^1.2.1" - parse-numeric-range "^1.3.0" - prism-react-renderer "^1.3.5" - tslib "^2.4.0" - use-sync-external-store "^1.2.0" - utility-types "^3.10.0" - -"@docusaurus/theme-mermaid@^2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-mermaid/-/theme-mermaid-2.4.3.tgz#b40194fb4f46813a18d1350a188d43b68a8192dd" - integrity sha512-S1tZ3xpowtFiTrpTKmvVbRHUYGOlEG5CnPzWlO4huJT1sAwLR+pD6f9DYUlPv2+9NezF3EfUrUyW9xLH0UP58w== - dependencies: - "@docusaurus/core" "2.4.3" - "@docusaurus/module-type-aliases" "2.4.3" - "@docusaurus/theme-common" "2.4.3" - "@docusaurus/types" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - "@mdx-js/react" "^1.6.22" - mermaid "^9.2.2" - tslib "^2.4.0" - -"@docusaurus/theme-search-algolia@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.4.3.tgz#32d4cbefc3deba4112068fbdb0bde11ac51ece53" - integrity sha512-jziq4f6YVUB5hZOB85ELATwnxBz/RmSLD3ksGQOLDPKVzat4pmI8tddNWtriPpxR04BNT+ZfpPUMFkNFetSW1Q== - dependencies: - "@docsearch/react" "^3.1.1" - "@docusaurus/core" "2.4.3" - "@docusaurus/logger" "2.4.3" - "@docusaurus/plugin-content-docs" "2.4.3" - "@docusaurus/theme-common" "2.4.3" - "@docusaurus/theme-translations" "2.4.3" - "@docusaurus/utils" "2.4.3" - "@docusaurus/utils-validation" "2.4.3" - algoliasearch "^4.13.1" - algoliasearch-helper "^3.10.0" - clsx "^1.2.1" - eta "^2.0.0" - fs-extra "^10.1.0" - lodash "^4.17.21" - tslib "^2.4.0" - utility-types "^3.10.0" - -"@docusaurus/theme-translations@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-2.4.3.tgz#91ac73fc49b8c652b7a54e88b679af57d6ac6102" - integrity sha512-H4D+lbZbjbKNS/Zw1Lel64PioUAIT3cLYYJLUf3KkuO/oc9e0QCVhIYVtUI2SfBCF2NNdlyhBDQEEMygsCedIg== - dependencies: - fs-extra "^10.1.0" - tslib "^2.4.0" - -"@docusaurus/types@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-2.4.3.tgz#4aead281ca09f721b3c0a9b926818450cfa3db31" - integrity sha512-W6zNLGQqfrp/EoPD0bhb9n7OobP+RHpmvVzpA+Z/IuU3Q63njJM24hmT0GYboovWcDtFmnIJC9wcyx4RVPQscw== - dependencies: - "@types/history" "^4.7.11" - "@types/react" "*" - commander "^5.1.0" - joi "^17.6.0" - react-helmet-async "^1.3.0" - utility-types "^3.10.0" - webpack "^5.73.0" - webpack-merge "^5.8.0" - -"@docusaurus/utils-common@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-2.4.3.tgz#30656c39ef1ce7e002af7ba39ea08330f58efcfb" - integrity sha512-/jascp4GbLQCPVmcGkPzEQjNaAk3ADVfMtudk49Ggb+131B1WDD6HqlSmDf8MxGdy7Dja2gc+StHf01kiWoTDQ== - dependencies: - tslib "^2.4.0" - -"@docusaurus/utils-validation@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-2.4.3.tgz#8122c394feef3e96c73f6433987837ec206a63fb" - integrity sha512-G2+Vt3WR5E/9drAobP+hhZQMaswRwDlp6qOMi7o7ZypB+VO7N//DZWhZEwhcRGepMDJGQEwtPv7UxtYwPL9PBw== - dependencies: - "@docusaurus/logger" "2.4.3" - "@docusaurus/utils" "2.4.3" - joi "^17.6.0" - js-yaml "^4.1.0" - tslib "^2.4.0" - -"@docusaurus/utils@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-2.4.3.tgz#52b000d989380a2125831b84e3a7327bef471e89" - integrity sha512-fKcXsjrD86Smxv8Pt0TBFqYieZZCPh4cbf9oszUq/AMhZn3ujwpKaVYZACPX8mmjtYx0JOgNx52CREBfiGQB4A== - dependencies: - "@docusaurus/logger" "2.4.3" - "@svgr/webpack" "^6.2.1" - escape-string-regexp "^4.0.0" - file-loader "^6.2.0" - fs-extra "^10.1.0" - github-slugger "^1.4.0" - globby "^11.1.0" - gray-matter "^4.0.3" - js-yaml "^4.1.0" - lodash "^4.17.21" - micromatch "^4.0.5" - resolve-pathname "^3.0.0" - shelljs "^0.8.5" - tslib "^2.4.0" - url-loader "^4.1.1" - webpack "^5.73.0" - -"@hapi/hoek@^9.0.0": - version "9.3.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" - integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== - -"@hapi/topo@^5.0.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" - integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== - dependencies: - "@hapi/hoek" "^9.0.0" - -"@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== - dependencies: - "@sinclair/typebox" "^0.27.8" - -"@jest/types@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" - integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== - dependencies: - "@jest/schemas" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/source-map@^0.3.3": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" - integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.19" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" - integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" - integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== - -"@mdx-js/mdx@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" - integrity sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA== - dependencies: - "@babel/core" "7.12.9" - "@babel/plugin-syntax-jsx" "7.12.1" - "@babel/plugin-syntax-object-rest-spread" "7.8.3" - "@mdx-js/util" "1.6.22" - babel-plugin-apply-mdx-type-prop "1.6.22" - babel-plugin-extract-import-names "1.6.22" - camelcase-css "2.0.1" - detab "2.0.4" - hast-util-raw "6.0.1" - lodash.uniq "4.5.0" - mdast-util-to-hast "10.0.1" - remark-footnotes "2.0.0" - remark-mdx "1.6.22" - remark-parse "8.0.3" - remark-squeeze-paragraphs "4.0.0" - style-to-object "0.3.0" - unified "9.2.0" - unist-builder "2.0.3" - unist-util-visit "2.0.3" - -"@mdx-js/react@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" - integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== - -"@mdx-js/util@1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" - integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@polka/url@^1.0.0-next.20": - version "1.0.0-next.23" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.23.tgz#498e41218ab3b6a1419c735e5c6ae2c5ed609b6c" - integrity sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg== - -"@sideway/address@^4.1.3": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" - integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== - dependencies: - "@hapi/hoek" "^9.0.0" - -"@sideway/formula@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" - integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== - -"@sideway/pinpoint@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" - integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== - -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - -"@slorber/static-site-generator-webpack-plugin@^4.0.7": - version "4.0.7" - resolved "https://registry.yarnpkg.com/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz#fc1678bddefab014e2145cbe25b3ce4e1cfc36f3" - integrity sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA== - dependencies: - eval "^0.1.8" - p-map "^4.0.0" - webpack-sources "^3.2.2" - -"@svgr/babel-plugin-add-jsx-attribute@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz#74a5d648bd0347bda99d82409d87b8ca80b9a1ba" - integrity sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ== - -"@svgr/babel-plugin-remove-jsx-attribute@*": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" - integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== - -"@svgr/babel-plugin-remove-jsx-empty-expression@*": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" - integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== - -"@svgr/babel-plugin-replace-jsx-attribute-value@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz#fb9d22ea26d2bc5e0a44b763d4c46d5d3f596c60" - integrity sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg== - -"@svgr/babel-plugin-svg-dynamic-title@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz#01b2024a2b53ffaa5efceaa0bf3e1d5a4c520ce4" - integrity sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw== - -"@svgr/babel-plugin-svg-em-dimensions@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz#dd3fa9f5b24eb4f93bcf121c3d40ff5facecb217" - integrity sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA== - -"@svgr/babel-plugin-transform-react-native-svg@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz#1d8e945a03df65b601551097d8f5e34351d3d305" - integrity sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg== - -"@svgr/babel-plugin-transform-svg-component@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz#48620b9e590e25ff95a80f811544218d27f8a250" - integrity sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ== - -"@svgr/babel-preset@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-6.5.1.tgz#b90de7979c8843c5c580c7e2ec71f024b49eb828" - integrity sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw== - dependencies: - "@svgr/babel-plugin-add-jsx-attribute" "^6.5.1" - "@svgr/babel-plugin-remove-jsx-attribute" "*" - "@svgr/babel-plugin-remove-jsx-empty-expression" "*" - "@svgr/babel-plugin-replace-jsx-attribute-value" "^6.5.1" - "@svgr/babel-plugin-svg-dynamic-title" "^6.5.1" - "@svgr/babel-plugin-svg-em-dimensions" "^6.5.1" - "@svgr/babel-plugin-transform-react-native-svg" "^6.5.1" - "@svgr/babel-plugin-transform-svg-component" "^6.5.1" - -"@svgr/core@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-6.5.1.tgz#d3e8aa9dbe3fbd747f9ee4282c1c77a27410488a" - integrity sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw== - dependencies: - "@babel/core" "^7.19.6" - "@svgr/babel-preset" "^6.5.1" - "@svgr/plugin-jsx" "^6.5.1" - camelcase "^6.2.0" - cosmiconfig "^7.0.1" - -"@svgr/hast-util-to-babel-ast@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz#81800bd09b5bcdb968bf6ee7c863d2288fdb80d2" - integrity sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw== - dependencies: - "@babel/types" "^7.20.0" - entities "^4.4.0" - -"@svgr/plugin-jsx@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz#0e30d1878e771ca753c94e69581c7971542a7072" - integrity sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw== - dependencies: - "@babel/core" "^7.19.6" - "@svgr/babel-preset" "^6.5.1" - "@svgr/hast-util-to-babel-ast" "^6.5.1" - svg-parser "^2.0.4" - -"@svgr/plugin-svgo@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz#0f91910e988fc0b842f88e0960c2862e022abe84" - integrity sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ== - dependencies: - cosmiconfig "^7.0.1" - deepmerge "^4.2.2" - svgo "^2.8.0" - -"@svgr/webpack@^6.2.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-6.5.1.tgz#ecf027814fc1cb2decc29dc92f39c3cf691e40e8" - integrity sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA== - dependencies: - "@babel/core" "^7.19.6" - "@babel/plugin-transform-react-constant-elements" "^7.18.12" - "@babel/preset-env" "^7.19.4" - "@babel/preset-react" "^7.18.6" - "@babel/preset-typescript" "^7.18.6" - "@svgr/core" "^6.5.1" - "@svgr/plugin-jsx" "^6.5.1" - "@svgr/plugin-svgo" "^6.5.1" - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== - -"@tsconfig/docusaurus@^1.0.5": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@tsconfig/docusaurus/-/docusaurus-1.0.7.tgz#a3ee3c8109b3fec091e3d61a61834e563aeee3c3" - integrity sha512-ffTXxGIP/IRMCjuzHd6M4/HdIrw1bMfC7Bv8hMkTadnePkpe0lG0oDSdbRpSDZb2rQMAgpbWiR10BvxvNYwYrg== - -"@types/body-parser@*": - version "1.19.3" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.3.tgz#fb558014374f7d9e56c8f34bab2042a3a07d25cd" - integrity sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.11" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.11.tgz#fbaa46a1529ea5c5e46cde36e4be6a880db55b84" - integrity sha512-isGhjmBtLIxdHBDl2xGwUzEM8AOyOvWsADWq7rqirdi/ZQoHnLWErHvsThcEzTX8juDRiZtzp2Qkv5bgNh6mAg== - dependencies: - "@types/node" "*" - -"@types/connect-history-api-fallback@^1.3.5": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.1.tgz#6e5e3602d93bda975cebc3449e1a318340af9e20" - integrity sha512-iaQslNbARe8fctL5Lk+DsmgWOM83lM+7FzP0eQUJs1jd3kBE8NWqBTIT2S8SqQOJjxvt2eyIjpOuYeRXq2AdMw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.36" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.36.tgz#e511558c15a39cb29bd5357eebb57bd1459cd1ab" - integrity sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w== - dependencies: - "@types/node" "*" - -"@types/eslint-scope@^3.7.3": - version "3.7.5" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.5.tgz#e28b09dbb1d9d35fdfa8a884225f00440dfc5a3e" - integrity sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.44.4" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.4.tgz#28eaff82e1ca0a96554ec5bb0188f10ae1a74c2f" - integrity sha512-lOzjyfY/D9QR4hY9oblZ76B90MYTB3RrQ4z2vBIJKj9ROCRqdkYl2gSUx1x1a4IWPjKJZLL4Aw1Zfay7eMnmnA== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.2.tgz#ff02bc3dc8317cd668dfec247b750ba1f1d62453" - integrity sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": - version "4.17.37" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz#7e4b7b59da9142138a2aaa7621f5abedce8c7320" - integrity sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express@*", "@types/express@^4.17.13": - version "4.17.19" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.19.tgz#6ff9b4851fda132c5d3dcd2f89fdb6a7a0031ced" - integrity sha512-UtOfBtzN9OvpZPPbnnYunfjM7XCI4jyk1NvnFhTVz5krYAnW4o5DCoIekvms+8ApqhB4+9wSge1kBijdfTSmfg== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/hast@^2.0.0": - version "2.3.6" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.6.tgz#bb8b05602112a26d22868acb70c4b20984ec7086" - integrity sha512-47rJE80oqPmFdVDCD7IheXBrVdwuBgsYwoczFvKmwfo2Mzsnt+V9OONsYauFmICb6lQPpCuXYJWejBNs4pDJRg== - dependencies: - "@types/unist" "^2" - -"@types/history@^4.7.11": - version "4.7.11" - resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" - integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== - -"@types/html-minifier-terser@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" - integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== - -"@types/http-errors@*": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.2.tgz#a86e00bbde8950364f8e7846687259ffcd96e8c2" - integrity sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg== - -"@types/http-proxy@^1.17.8": - version "1.17.12" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.12.tgz#86e849e9eeae0362548803c37a0a1afc616bd96b" - integrity sha512-kQtujO08dVtQ2wXAuSFfk9ASy3sug4+ogFR8Kd8UgP8PEuc1/G/8yjYRmp//PcDNJEUKOza/MrQu15bouEUCiw== - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== - -"@types/istanbul-lib-report@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#412e0725ef41cde73bfa03e0e833eaff41e0fd63" - integrity sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.2.tgz#edc8e421991a3b4df875036d381fc0a5a982f549" - integrity sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.13" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85" - integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ== - -"@types/katex@^0.11.0": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.11.1.tgz#34de04477dcf79e2ef6c8d23b41a3d81f9ebeaf5" - integrity sha512-DUlIj2nk0YnJdlWgsFuVKcX27MLW0KbKmGVoUHmFr+74FYYNUDAaj9ZqTADvsbE8rfxuVmSFc7KczYn5Y09ozg== - -"@types/mdast@^3.0.0": - version "3.0.13" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.13.tgz#b7ba6e52d0faeb9c493e32c205f3831022be4e1b" - integrity sha512-HjiGiWedR0DVFkeNljpa6Lv4/IZU1+30VY5d747K7lBudFc3R0Ibr6yJ9lN3BE28VnZyDfLF/VB1Ql1ZIbKrmg== - dependencies: - "@types/unist" "^2" - -"@types/mime@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.2.tgz#c1ae807f13d308ee7511a5b81c74f327028e66e8" - integrity sha512-Wj+fqpTLtTbG7c0tH47dkahefpLKEbB+xAZuLq7b4/IDHPl/n6VoXcyUQ2bypFlbSwvCr0y+bD4euTTqTJsPxQ== - -"@types/mime@^1": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.3.tgz#bbe64987e0eb05de150c305005055c7ad784a9ce" - integrity sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg== - -"@types/node@*": - version "20.8.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.4.tgz#0e9ebb2ff29d5c3302fc84477d066fa7c6b441aa" - integrity sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A== - dependencies: - undici-types "~5.25.1" - -"@types/node@^17.0.5": - version "17.0.45" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" - integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/parse5@^5.0.0": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" - integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== - -"@types/prop-types@*": - version "15.7.8" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.8.tgz#805eae6e8f41bd19e88917d2ea200dc992f405d3" - integrity sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ== - -"@types/qs@*": - version "6.9.8" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.8.tgz#f2a7de3c107b89b441e071d5472e6b726b4adf45" - integrity sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg== - -"@types/range-parser@*": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.5.tgz#38bd1733ae299620771bd414837ade2e57757498" - integrity sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA== - -"@types/react-router-config@*", "@types/react-router-config@^5.0.6": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@types/react-router-config/-/react-router-config-5.0.8.tgz#dd00654de4d79927570a4a8807c4a728feed59f3" - integrity sha512-zBzYZsr05V9xRG96oQ/xBXHy5+fDCX5wL7bboM0FFoOYQp9Gxmz8uvuKSkLesNWHlICl+W1l64F7fmp/KsOkuw== - dependencies: - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-router" "^5.1.0" - -"@types/react-router-dom@*": - version "5.3.3" - resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" - integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== - dependencies: - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-router" "*" - -"@types/react-router@*", "@types/react-router@^5.1.0": - version "5.1.20" - resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c" - integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== - dependencies: - "@types/history" "^4.7.11" - "@types/react" "*" - -"@types/react@*": - version "18.2.27" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.27.tgz#746e52b06f3ccd5d7a724fd53769b70792601440" - integrity sha512-Wfv7B7FZiR2r3MIqbAlXoY1+tXm4bOqfz4oRr+nyXdBqapDBZ0l/IGcSlAfvxIHEEJjkPU0MYAc/BlFPOcrgLw== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== - -"@types/sax@^1.2.1": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@types/sax/-/sax-1.2.5.tgz#4392799e1770d24b6dc8d0c66c8882f8e1c38b3d" - integrity sha512-9jWta97bBVC027/MShr3gLab8gPhKy4l6qpb+UJLF5pDm3501NvA7uvqVCW+REFtx00oTi6Cq9JzLwgq6evVgw== - dependencies: - "@types/node" "*" - -"@types/scheduler@*": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.4.tgz#fedc3e5b15c26dc18faae96bf1317487cb3658cf" - integrity sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ== - -"@types/send@*": - version "0.17.2" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.2.tgz#af78a4495e3c2b79bfbdac3955fdd50e03cc98f2" - integrity sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/serve-index@^1.9.1": - version "1.9.2" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.2.tgz#cb26e775678a8526b73a5d980a147518740aaecd" - integrity sha512-asaEIoc6J+DbBKXtO7p2shWUpKacZOoMBEGBgPG91P8xhO53ohzHWGCs4ScZo5pQMf5ukQzVT9fhX1WzpHihig== - dependencies: - "@types/express" "*" - -"@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.3" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.3.tgz#2cfacfd1fd4520bbc3e292cca432d5e8e2e3ee61" - integrity sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg== - dependencies: - "@types/http-errors" "*" - "@types/mime" "*" - "@types/node" "*" - -"@types/sockjs@^0.3.33": - version "0.3.34" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.34.tgz#43e10e549b36d2ba2589278f00f81b5d7ccda167" - integrity sha512-R+n7qBFnm/6jinlteC9DBL5dGiDGjWAvjo4viUanpnc/dG1y7uDoacXPIQ/PQEg1fI912SMHIa014ZjRpvDw4g== - dependencies: - "@types/node" "*" - -"@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.8.tgz#bb197b9639aa1a04cf464a617fe800cccd92ad5c" - integrity sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw== - -"@types/ws@^8.5.5": - version "8.5.6" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.6.tgz#e9ad51f0ab79b9110c50916c9fcbddc36d373065" - integrity sha512-8B5EO9jLVCy+B58PLHvLDuOD8DRVMgQzq8d55SjLCOn9kqGyqOvy27exVaTio1q1nX5zLu8/6N0n2ThSxOM6tg== - dependencies: - "@types/node" "*" - -"@types/yargs-parser@*": - version "21.0.1" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.1.tgz#07773d7160494d56aa882d7531aac7319ea67c3b" - integrity sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ== - -"@types/yargs@^17.0.8": - version "17.0.28" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.28.tgz#d106e4301fbacde3d1796ab27374dd16588ec851" - integrity sha512-N3e3fkS86hNhtk6BEnc0rj3zcehaxx8QWhCROJkqpl5Zaoi7nAic3jH8q94jVD3zu5LGk+PUB6KAiDmimYOEQw== - dependencies: - "@types/yargs-parser" "*" - -"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" - integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - -"@webassemblyjs/floating-point-hex-parser@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" - integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== - -"@webassemblyjs/helper-api-error@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" - integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== - -"@webassemblyjs/helper-buffer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" - integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== - -"@webassemblyjs/helper-numbers@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" - integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.6" - "@webassemblyjs/helper-api-error" "1.11.6" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" - integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== - -"@webassemblyjs/helper-wasm-section@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" - integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - -"@webassemblyjs/ieee754@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" - integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" - integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" - integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== - -"@webassemblyjs/wasm-edit@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" - integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-opt" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" - "@webassemblyjs/wast-printer" "1.11.6" - -"@webassemblyjs/wasm-gen@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" - integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" - -"@webassemblyjs/wasm-opt@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" - integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" - -"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" - integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-api-error" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" - -"@webassemblyjs/wast-printer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" - integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-import-assertions@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" - integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== - -acorn-walk@^8.0.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.0.4, acorn@^8.7.1, acorn@^8.8.2: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== - -address@^1.0.1, address@^1.1.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" - integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.0, ajv@^8.9.0: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -algoliasearch-helper@^3.10.0: - version "3.14.2" - resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.14.2.tgz#c34cfe6cefcfecd65c60bcb8bf9b68134472d28c" - integrity sha512-FjDSrjvQvJT/SKMW74nPgFpsoPUwZCzGbCqbp8HhBFfSk/OvNFxzCaCmuO0p7AWeLy1gD+muFwQEkBwcl5H4pg== - dependencies: - "@algolia/events" "^4.0.1" - -algoliasearch@^4.13.1, algoliasearch@^4.19.1: - version "4.20.0" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.20.0.tgz#700c2cb66e14f8a288460036c7b2a554d0d93cf4" - integrity sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g== - dependencies: - "@algolia/cache-browser-local-storage" "4.20.0" - "@algolia/cache-common" "4.20.0" - "@algolia/cache-in-memory" "4.20.0" - "@algolia/client-account" "4.20.0" - "@algolia/client-analytics" "4.20.0" - "@algolia/client-common" "4.20.0" - "@algolia/client-personalization" "4.20.0" - "@algolia/client-search" "4.20.0" - "@algolia/logger-common" "4.20.0" - "@algolia/logger-console" "4.20.0" - "@algolia/requester-browser-xhr" "4.20.0" - "@algolia/requester-common" "4.20.0" - "@algolia/requester-node-http" "4.20.0" - "@algolia/transporter" "4.20.0" - -ansi-align@^3.0.0, ansi-align@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" - integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== - dependencies: - string-width "^4.1.0" - -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" - integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -autoprefixer@^10.4.12, autoprefixer@^10.4.7: - version "10.4.16" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.16.tgz#fad1411024d8670880bdece3970aa72e3572feb8" - integrity sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ== - dependencies: - browserslist "^4.21.10" - caniuse-lite "^1.0.30001538" - fraction.js "^4.3.6" - normalize-range "^0.1.2" - picocolors "^1.0.0" - postcss-value-parser "^4.2.0" - -axios@^0.25.0: - version "0.25.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a" - integrity sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g== - dependencies: - follow-redirects "^1.14.7" - -babel-loader@^8.2.5: - version "8.3.0" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" - integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== - dependencies: - find-cache-dir "^3.3.1" - loader-utils "^2.0.0" - make-dir "^3.1.0" - schema-utils "^2.6.5" - -babel-plugin-apply-mdx-type-prop@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz#d216e8fd0de91de3f1478ef3231e05446bc8705b" - integrity sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - "@mdx-js/util" "1.6.22" - -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-extract-import-names@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz#de5f9a28eb12f3eb2578bf74472204e66d1a13dc" - integrity sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - -babel-plugin-polyfill-corejs2@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz#8097b4cb4af5b64a1d11332b6fb72ef5e64a054c" - integrity sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg== - dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.4.2" - semver "^6.3.1" - -babel-plugin-polyfill-corejs3@^0.8.3: - version "0.8.4" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.4.tgz#1fac2b1dcef6274e72b3c72977ed8325cb330591" - integrity sha512-9l//BZZsPR+5XjyJMPtZSK4jv0BsTO1zDac2GC6ygx9WLGlcsnRd1Co0B2zT5fF5Ic6BZy+9m3HNZ3QcOeDKfg== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.2" - core-js-compat "^3.32.2" - -babel-plugin-polyfill-regenerator@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz#80d0f3e1098c080c8b5a65f41e9427af692dc326" - integrity sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.2" - -bail@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" - integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base16@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" - integrity sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ== - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - -bonjour-service@^1.0.11: - version "1.1.1" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" - integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== - dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - -boxen@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - -boxen@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-6.2.1.tgz#b098a2278b2cd2845deef2dff2efc38d329b434d" - integrity sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw== - dependencies: - ansi-align "^3.0.1" - camelcase "^6.2.0" - chalk "^4.1.2" - cli-boxes "^3.0.0" - string-width "^5.0.1" - type-fest "^2.5.0" - widest-line "^4.0.1" - wrap-ansi "^8.0.1" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.9, browserslist@^4.22.1: - version "4.22.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" - integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== - dependencies: - caniuse-lite "^1.0.30001541" - electron-to-chromium "^1.4.535" - node-releases "^2.0.13" - update-browserslist-db "^1.0.13" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camel-case@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" - integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== - dependencies: - pascal-case "^3.1.2" - tslib "^2.0.3" - -camelcase-css@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" - integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== - -camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001541: - version "1.0.30001547" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz#d4f92efc488aab3c7f92c738d3977c2a3180472b" - integrity sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA== - -ccount@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" - integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== - -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== - -character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== - -character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== - -cheerio-select@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" - integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== - dependencies: - boolbase "^1.0.0" - css-select "^5.1.0" - css-what "^6.1.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - -cheerio@^1.0.0-rc.12: - version "1.0.0-rc.12" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" - integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== - dependencies: - cheerio-select "^2.1.0" - dom-serializer "^2.0.0" - domhandler "^5.0.3" - domutils "^3.0.1" - htmlparser2 "^8.0.1" - parse5 "^7.0.0" - parse5-htmlparser2-tree-adapter "^7.0.0" - -chokidar@^3.4.2, chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -ci-info@^3.2.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" - integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== - -clean-css@^5.2.2, clean-css@^5.3.0: - version "5.3.2" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" - integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== - dependencies: - source-map "~0.6.0" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - -cli-boxes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145" - integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g== - -cli-table3@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" - integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== - dependencies: - string-width "^4.2.0" - optionalDependencies: - "@colors/colors" "1.5.0" - -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" - integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== - dependencies: - mimic-response "^1.0.0" - -clsx@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" - integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== - -collapse-white-space@^1.0.2: - version "1.0.6" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" - integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colord@^2.9.1: - version "2.9.3" - resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" - integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== - -colorette@^2.0.10: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -combine-promises@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/combine-promises/-/combine-promises-1.2.0.tgz#5f2e68451862acf85761ded4d9e2af7769c2ca6a" - integrity sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ== - -comma-separated-tokens@^1.0.0: - version "1.0.8" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" - integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== - -commander@7, commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" - integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== - -commander@^8.0.0, commander@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -configstore@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" - integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== - dependencies: - dot-prop "^5.2.0" - graceful-fs "^4.1.2" - make-dir "^3.0.0" - unique-string "^2.0.0" - write-file-atomic "^3.0.0" - xdg-basedir "^4.0.0" - -connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" - integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== - -consola@^2.15.3: - version "2.15.3" - resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" - integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== - -content-disposition@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" - integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA== - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - -copy-text-to-clipboard@^3.0.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz#0202b2d9bdae30a49a53f898626dcc3b49ad960b" - integrity sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q== - -copy-webpack-plugin@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a" - integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ== - dependencies: - fast-glob "^3.2.11" - glob-parent "^6.0.1" - globby "^13.1.1" - normalize-path "^3.0.0" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - -core-js-compat@^3.31.0, core-js-compat@^3.32.2: - version "3.33.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.0.tgz#24aa230b228406450b2277b7c8bfebae932df966" - integrity sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw== - dependencies: - browserslist "^4.22.1" - -core-js-pure@^3.30.2: - version "3.33.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.0.tgz#938a28754b4d82017a7a8cbd2727b1abecc63591" - integrity sha512-FKSIDtJnds/YFIEaZ4HszRX7hkxGpNKM7FC9aJ9WLJbSd3lD4vOltFuVIBLR8asSx9frkTSqL0dw90SKQxgKrg== - -core-js@^3.23.3: - version "3.33.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.0.tgz#70366dbf737134761edb017990cf5ce6c6369c40" - integrity sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cose-base@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-1.0.3.tgz#650334b41b869578a543358b80cda7e0abe0a60a" - integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg== - dependencies: - layout-base "^1.0.0" - -cose-base@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-2.2.0.tgz#1c395c35b6e10bb83f9769ca8b817d614add5c01" - integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== - dependencies: - layout-base "^2.0.0" - -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - -cosmiconfig@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" - integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -cosmiconfig@^8.2.0: - version "8.3.6" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" - integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== - dependencies: - import-fresh "^3.3.0" - js-yaml "^4.1.0" - parse-json "^5.2.0" - path-type "^4.0.0" - -cross-fetch@^3.1.5: - version "3.1.8" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" - integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== - dependencies: - node-fetch "^2.6.12" - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - -css-declaration-sorter@^6.3.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" - integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== - -css-loader@^6.7.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.8.1.tgz#0f8f52699f60f5e679eab4ec0fcd68b8e8a50a88" - integrity sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g== - dependencies: - icss-utils "^5.1.0" - postcss "^8.4.21" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.3" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.2.0" - semver "^7.3.8" - -css-minimizer-webpack-plugin@^4.0.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz#79f6199eb5adf1ff7ba57f105e3752d15211eb35" - integrity sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA== - dependencies: - cssnano "^5.1.8" - jest-worker "^29.1.2" - postcss "^8.4.17" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - -css-select@^4.1.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" - integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== - dependencies: - boolbase "^1.0.0" - css-what "^6.0.1" - domhandler "^4.3.1" - domutils "^2.8.0" - nth-check "^2.0.1" - -css-select@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" - integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== - dependencies: - boolbase "^1.0.0" - css-what "^6.1.0" - domhandler "^5.0.2" - domutils "^3.0.1" - nth-check "^2.0.1" - -css-tree@^1.1.2, css-tree@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - -css-what@^6.0.1, css-what@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -cssnano-preset-advanced@^5.3.8: - version "5.3.10" - resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.10.tgz#25558a1fbf3a871fb6429ce71e41be7f5aca6eef" - integrity sha512-fnYJyCS9jgMU+cmHO1rPSPf9axbQyD7iUhLO5Df6O4G+fKIOMps+ZbU0PdGFejFBBZ3Pftf18fn1eG7MAPUSWQ== - dependencies: - autoprefixer "^10.4.12" - cssnano-preset-default "^5.2.14" - postcss-discard-unused "^5.1.0" - postcss-merge-idents "^5.1.1" - postcss-reduce-idents "^5.2.0" - postcss-zindex "^5.1.0" - -cssnano-preset-default@^5.2.14: - version "5.2.14" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" - integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A== - dependencies: - css-declaration-sorter "^6.3.1" - cssnano-utils "^3.1.0" - postcss-calc "^8.2.3" - postcss-colormin "^5.3.1" - postcss-convert-values "^5.1.3" - postcss-discard-comments "^5.1.2" - postcss-discard-duplicates "^5.1.0" - postcss-discard-empty "^5.1.1" - postcss-discard-overridden "^5.1.0" - postcss-merge-longhand "^5.1.7" - postcss-merge-rules "^5.1.4" - postcss-minify-font-values "^5.1.0" - postcss-minify-gradients "^5.1.1" - postcss-minify-params "^5.1.4" - postcss-minify-selectors "^5.2.1" - postcss-normalize-charset "^5.1.0" - postcss-normalize-display-values "^5.1.0" - postcss-normalize-positions "^5.1.1" - postcss-normalize-repeat-style "^5.1.1" - postcss-normalize-string "^5.1.0" - postcss-normalize-timing-functions "^5.1.0" - postcss-normalize-unicode "^5.1.1" - postcss-normalize-url "^5.1.0" - postcss-normalize-whitespace "^5.1.1" - postcss-ordered-values "^5.1.3" - postcss-reduce-initial "^5.1.2" - postcss-reduce-transforms "^5.1.0" - postcss-svgo "^5.1.0" - postcss-unique-selectors "^5.1.1" - -cssnano-utils@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" - integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== - -cssnano@^5.1.12, cssnano@^5.1.8: - version "5.1.15" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" - integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== - dependencies: - cssnano-preset-default "^5.2.14" - lilconfig "^2.0.3" - yaml "^1.10.2" - -csso@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== - dependencies: - css-tree "^1.1.2" - -csstype@^3.0.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== - -cytoscape-cose-bilkent@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz#762fa121df9930ffeb51a495d87917c570ac209b" - integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ== - dependencies: - cose-base "^1.0.0" - -cytoscape-fcose@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz#e4d6f6490df4fab58ae9cea9e5c3ab8d7472f471" - integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== - dependencies: - cose-base "^2.2.0" - -cytoscape@^3.23.0: - version "3.27.0" - resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.27.0.tgz#5141cd694570807c91075b609181bce102e0bb88" - integrity sha512-pPZJilfX9BxESwujODz5pydeGi+FBrXq1rcaB1mfhFXXFJ9GjE6CNndAk+8jPzoXGD+16LtSS4xlYEIUiW4Abg== - dependencies: - heap "^0.2.6" - lodash "^4.17.21" - -"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" - integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== - dependencies: - internmap "1 - 2" - -d3-axis@3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-3.0.0.tgz#c42a4a13e8131d637b745fc2973824cfeaf93322" - integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw== - -d3-brush@3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-3.0.0.tgz#6f767c4ed8dcb79de7ede3e1c0f89e63ef64d31c" - integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ== - dependencies: - d3-dispatch "1 - 3" - d3-drag "2 - 3" - d3-interpolate "1 - 3" - d3-selection "3" - d3-transition "3" - -d3-chord@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-3.0.1.tgz#d156d61f485fce8327e6abf339cb41d8cbba6966" - integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g== - dependencies: - d3-path "1 - 3" - -"d3-color@1 - 3", d3-color@3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" - integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== - -d3-contour@4: - version "4.0.2" - resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-4.0.2.tgz#bb92063bc8c5663acb2422f99c73cbb6c6ae3bcc" - integrity sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA== - dependencies: - d3-array "^3.2.0" - -d3-delaunay@6: - version "6.0.4" - resolved "https://registry.yarnpkg.com/d3-delaunay/-/d3-delaunay-6.0.4.tgz#98169038733a0a5babbeda55054f795bb9e4a58b" - integrity sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A== - dependencies: - delaunator "5" - -"d3-dispatch@1 - 3", d3-dispatch@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e" - integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== - -"d3-drag@2 - 3", d3-drag@3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba" - integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== - dependencies: - d3-dispatch "1 - 3" - d3-selection "3" - -"d3-dsv@1 - 3", d3-dsv@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-3.0.1.tgz#c63af978f4d6a0d084a52a673922be2160789b73" - integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== - dependencies: - commander "7" - iconv-lite "0.6" - rw "1" - -"d3-ease@1 - 3", d3-ease@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" - integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== - -d3-fetch@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-3.0.1.tgz#83141bff9856a0edb5e38de89cdcfe63d0a60a22" - integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw== - dependencies: - d3-dsv "1 - 3" - -d3-force@3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-3.0.0.tgz#3e2ba1a61e70888fe3d9194e30d6d14eece155c4" - integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== - dependencies: - d3-dispatch "1 - 3" - d3-quadtree "1 - 3" - d3-timer "1 - 3" - -"d3-format@1 - 3", d3-format@3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" - integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== - -d3-geo@3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-3.1.0.tgz#74fd54e1f4cebd5185ac2039217a98d39b0a4c0e" - integrity sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA== - dependencies: - d3-array "2.5.0 - 3" - -d3-hierarchy@3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz#b01cd42c1eed3d46db77a5966cf726f8c09160c6" - integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== - -"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" - integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== - dependencies: - d3-color "1 - 3" - -"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" - integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== - -d3-polygon@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-3.0.1.tgz#0b45d3dd1c48a29c8e057e6135693ec80bf16398" - integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== - -"d3-quadtree@1 - 3", d3-quadtree@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-3.0.1.tgz#6dca3e8be2b393c9a9d514dabbd80a92deef1a4f" - integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== - -d3-random@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-3.0.1.tgz#d4926378d333d9c0bfd1e6fa0194d30aebaa20f4" - integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== - -d3-scale-chromatic@3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz#15b4ceb8ca2bb0dcb6d1a641ee03d59c3b62376a" - integrity sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g== - dependencies: - d3-color "1 - 3" - d3-interpolate "1 - 3" - -d3-scale@4: - version "4.0.2" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" - integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== - dependencies: - d3-array "2.10.0 - 3" - d3-format "1 - 3" - d3-interpolate "1.2.0 - 3" - d3-time "2.1.1 - 3" - d3-time-format "2 - 4" - -"d3-selection@2 - 3", d3-selection@3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31" - integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== - -d3-shape@3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" - integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== - dependencies: - d3-path "^3.1.0" - -"d3-time-format@2 - 4", d3-time-format@4: - version "4.1.0" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" - integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== - dependencies: - d3-time "1 - 3" - -"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" - integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== - dependencies: - d3-array "2 - 3" - -"d3-timer@1 - 3", d3-timer@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" - integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== - -"d3-transition@2 - 3", d3-transition@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f" - integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== - dependencies: - d3-color "1 - 3" - d3-dispatch "1 - 3" - d3-ease "1 - 3" - d3-interpolate "1 - 3" - d3-timer "1 - 3" - -d3-zoom@3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3" - integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== - dependencies: - d3-dispatch "1 - 3" - d3-drag "2 - 3" - d3-interpolate "1 - 3" - d3-selection "2 - 3" - d3-transition "2 - 3" - -d3@^7.4.0, d3@^7.8.2: - version "7.8.5" - resolved "https://registry.yarnpkg.com/d3/-/d3-7.8.5.tgz#fde4b760d4486cdb6f0cc8e2cbff318af844635c" - integrity sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA== - dependencies: - d3-array "3" - d3-axis "3" - d3-brush "3" - d3-chord "3" - d3-color "3" - d3-contour "4" - d3-delaunay "6" - d3-dispatch "3" - d3-drag "3" - d3-dsv "3" - d3-ease "3" - d3-fetch "3" - d3-force "3" - d3-format "3" - d3-geo "3" - d3-hierarchy "3" - d3-interpolate "3" - d3-path "3" - d3-polygon "3" - d3-quadtree "3" - d3-random "3" - d3-scale "4" - d3-scale-chromatic "3" - d3-selection "3" - d3-shape "3" - d3-time "3" - d3-time-format "4" - d3-timer "3" - d3-transition "3" - d3-zoom "3" - -dagre-d3-es@7.0.9: - version "7.0.9" - resolved "https://registry.yarnpkg.com/dagre-d3-es/-/dagre-d3-es-7.0.9.tgz#aca12fccd9d09955a4430029ba72ee6934542a8d" - integrity sha512-rYR4QfVmy+sR44IBDvVtcAmOReGBvRCWDpO2QjYwqgh9yijw6eSHBqaPG/LIOEy7aBsniLvtMW6pg19qJhq60w== - dependencies: - d3 "^7.8.2" - lodash-es "^4.17.21" - -dayjs@^1.11.7: - version "1.11.10" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" - integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== - -debug@2.6.9, debug@^2.6.0: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== - dependencies: - mimic-response "^1.0.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deepmerge@^4.2.2: - version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - -define-data-property@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.0.tgz#0db13540704e1d8d479a0656cf781267531b9451" - integrity sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g== - dependencies: - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -define-properties@^1.1.4: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -del@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" - integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - -delaunator@5: - version "5.0.0" - resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.0.tgz#60f052b28bd91c9b4566850ebf7756efe821d81b" - integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw== - dependencies: - robust-predicates "^3.0.0" - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detab@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.4.tgz#b927892069aff405fbb9a186fe97a44a92a94b43" - integrity sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g== - dependencies: - repeat-string "^1.5.4" - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -detect-port-alt@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" - integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== - dependencies: - address "^1.0.1" - debug "^2.6.0" - -detect-port@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== - dependencies: - address "^1.0.1" - debug "4" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== - -dns-packet@^5.2.2: - version "5.6.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" - integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - -dom-converter@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== - dependencies: - utila "~0.4" - -dom-serializer@^1.0.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" - integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" - -dom-serializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" - integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - entities "^4.2.0" - -domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" - integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== - dependencies: - domelementtype "^2.2.0" - -domhandler@^5.0.2, domhandler@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" - integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== - dependencies: - domelementtype "^2.3.0" - -dompurify@2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.3.tgz#f4133af0e6a50297fc8874e2eaedc13a3c308c03" - integrity sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ== - -domutils@^2.5.2, domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - -domutils@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" - integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== - dependencies: - dom-serializer "^2.0.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -dot-prop@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - -duplexer3@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" - integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== - -duplexer@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -electron-to-chromium@^1.4.535: - version "1.4.549" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.549.tgz#ab223f5d85c55a9def358db163bc8cacba72df69" - integrity sha512-gpXfJslSi4hYDkA0mTLEpYKRv9siAgSUgZ+UWyk+J5Cttpd1ThCVwdclzIwQSclz3hYn049+M2fgrP1WpvF8xg== - -elkjs@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/elkjs/-/elkjs-0.8.2.tgz#c37763c5a3e24e042e318455e0147c912a7c248e" - integrity sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - -emoticon@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/emoticon/-/emoticon-3.2.0.tgz#c008ca7d7620fac742fe1bf4af8ff8fed154ae7f" - integrity sha512-SNujglcLTTg+lDAcApPNgEdudaqQFiAbJCqzjNxJkvN9vAwCGi0uu8IUVvx+f16h+V44KCY6Y2yboroc9pilHg== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enhanced-resolve@^5.15.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - -entities@^4.2.0, entities@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" - integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-module-lexer@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.1.tgz#c1b0dd5ada807a3b3155315911f364dc4e909db1" - integrity sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-goat@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" - integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== - -escape-html@^1.0.3, escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -eta@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eta/-/eta-2.2.0.tgz#eb8b5f8c4e8b6306561a455e62cd7492fe3a9b8a" - integrity sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -eval@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/eval/-/eval-0.1.8.tgz#2b903473b8cc1d1989b83a1e7923f883eb357f85" - integrity sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw== - dependencies: - "@types/node" "*" - require-like ">= 0.1.1" - -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -express@^4.17.3: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.1" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.11.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - -extend@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.2.11, fast-glob@^3.2.9, fast-glob@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-url-parser@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" - integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ== - dependencies: - punycode "^1.3.2" - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - -fbemitter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-3.0.0.tgz#00b2a1af5411254aab416cd75f9e6289bee4bff3" - integrity sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw== - dependencies: - fbjs "^3.0.0" - -fbjs-css-vars@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" - integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== - -fbjs@^3.0.0, fbjs@^3.0.1: - version "3.0.5" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.5.tgz#aa0edb7d5caa6340011790bd9249dbef8a81128d" - integrity sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg== - dependencies: - cross-fetch "^3.1.5" - fbjs-css-vars "^1.0.0" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^1.0.35" - -feed@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e" - integrity sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ== - dependencies: - xml-js "^1.6.11" - -file-loader@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" - integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -filesize@^8.0.6: - version "8.0.7" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" - integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ== - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flux@^4.0.1: - version "4.0.4" - resolved "https://registry.yarnpkg.com/flux/-/flux-4.0.4.tgz#9661182ea81d161ee1a6a6af10d20485ef2ac572" - integrity sha512-NCj3XlayA2UsapRpM7va6wU1+9rE5FIL7qoMcmxWHRzbp0yujihMBm9BBHZ1MDIk5h5o2Bl6eGiCe8rYELAmYw== - dependencies: - fbemitter "^3.0.0" - fbjs "^3.0.1" - -follow-redirects@^1.0.0, follow-redirects@^1.14.7: - version "1.15.3" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" - integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== - -fork-ts-checker-webpack-plugin@^6.5.0: - version "6.5.3" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" - integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== - dependencies: - "@babel/code-frame" "^7.8.3" - "@types/json-schema" "^7.0.5" - chalk "^4.1.0" - chokidar "^3.4.2" - cosmiconfig "^6.0.0" - deepmerge "^4.2.2" - fs-extra "^9.0.0" - glob "^7.1.6" - memfs "^3.1.2" - minimatch "^3.0.4" - schema-utils "2.7.0" - semver "^7.3.2" - tapable "^1.0.0" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fraction.js@^4.3.6: - version "4.3.6" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.6.tgz#e9e3acec6c9a28cf7bc36cbe35eea4ceb2c5c92d" - integrity sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fs-extra@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-monkey@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" - integrity sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" - -get-own-enumerable-property-symbols@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" - integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== - -get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -github-slugger@^1.4.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" - integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -glob@^7.0.0, glob@^7.1.3, glob@^7.1.6: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-dirs@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" - integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== - dependencies: - ini "2.0.0" - -global-modules@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globby@^11.0.1, globby@^11.0.4, globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -globby@^13.1.1: - version "13.2.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.2.tgz#63b90b1bf68619c2135475cbd4e71e66aa090592" - integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.3.0" - ignore "^5.2.4" - merge2 "^1.4.1" - slash "^4.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -got@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -gray-matter@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" - integrity sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q== - dependencies: - js-yaml "^3.13.1" - kind-of "^6.0.2" - section-matter "^1.0.0" - strip-bom-string "^1.0.0" - -gzip-size@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" - integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== - dependencies: - duplexer "^0.1.2" - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-yarn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" - integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== - -has@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" - integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== - -hast-to-hyperscript@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" - integrity sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA== - dependencies: - "@types/unist" "^2.0.3" - comma-separated-tokens "^1.0.0" - property-information "^5.3.0" - space-separated-tokens "^1.0.0" - style-to-object "^0.3.0" - unist-util-is "^4.0.0" - web-namespaces "^1.0.0" - -hast-util-from-parse5@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" - integrity sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA== - dependencies: - "@types/parse5" "^5.0.0" - hastscript "^6.0.0" - property-information "^5.0.0" - vfile "^4.0.0" - vfile-location "^3.2.0" - web-namespaces "^1.0.0" - -hast-util-is-element@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz#3b3ed5159a2707c6137b48637fbfe068e175a425" - integrity sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ== - -hast-util-parse-selector@^2.0.0: - version "2.2.5" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" - integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== - -hast-util-raw@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.0.1.tgz#973b15930b7529a7b66984c98148b46526885977" - integrity sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig== - dependencies: - "@types/hast" "^2.0.0" - hast-util-from-parse5 "^6.0.0" - hast-util-to-parse5 "^6.0.0" - html-void-elements "^1.0.0" - parse5 "^6.0.0" - unist-util-position "^3.0.0" - vfile "^4.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.0" - zwitch "^1.0.0" - -hast-util-to-parse5@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" - integrity sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ== - dependencies: - hast-to-hyperscript "^9.0.0" - property-information "^5.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.0" - zwitch "^1.0.0" - -hast-util-to-text@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz#04f2e065642a0edb08341976084aa217624a0f8b" - integrity sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ== - dependencies: - hast-util-is-element "^1.0.0" - repeat-string "^1.0.0" - unist-util-find-after "^3.0.0" - -hastscript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" - integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== - dependencies: - "@types/hast" "^2.0.0" - comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.0.0" - property-information "^5.0.0" - space-separated-tokens "^1.0.0" - -he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -heap@^0.2.6: - version "0.2.7" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" - integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== - -history@^4.9.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" - integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== - dependencies: - "@babel/runtime" "^7.1.2" - loose-envify "^1.2.0" - resolve-pathname "^3.0.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - value-equal "^1.0.1" - -hoist-non-react-statics@^3.1.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-entities@^2.3.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" - integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== - -html-minifier-terser@^6.0.2, html-minifier-terser@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" - integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== - dependencies: - camel-case "^4.1.2" - clean-css "^5.2.2" - commander "^8.3.0" - he "^1.2.0" - param-case "^3.0.4" - relateurl "^0.2.7" - terser "^5.10.0" - -html-tags@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" - integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== - -html-void-elements@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" - integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== - -html-webpack-plugin@^5.5.0: - version "5.5.3" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz#72270f4a78e222b5825b296e5e3e1328ad525a3e" - integrity sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg== - dependencies: - "@types/html-minifier-terser" "^6.0.0" - html-minifier-terser "^6.0.2" - lodash "^4.17.21" - pretty-error "^4.0.0" - tapable "^2.0.0" - -htmlparser2@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" - integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" - domutils "^2.5.2" - entities "^2.0.0" - -htmlparser2@^8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" - integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - entities "^4.4.0" - -http-cache-semantics@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.8" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" - integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== - -http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@0.6: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - -ignore@^5.2.0, ignore@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -image-size@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.2.tgz#d778b6d0ab75b2737c1556dd631652eb963bc486" - integrity sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg== - dependencies: - queue "6.0.2" - -immer@^9.0.7: - version "9.0.21" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" - integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== - -import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A== - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -infima@0.2.0-alpha.43: - version "0.2.0-alpha.43" - resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.43.tgz#f7aa1d7b30b6c08afef441c726bac6150228cbe0" - integrity sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== - -ini@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== - -ini@^1.3.5, ini@~1.3.0: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -inline-style-parser@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" - integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== - -"internmap@1 - 2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" - integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" - integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== - -is-alphabetical@1.0.4, is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== - -is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-buffer@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-core-module@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== - dependencies: - has "^1.0.3" - -is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extendable@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== - -is-installed-globally@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" - integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== - dependencies: - global-dirs "^3.0.0" - is-path-inside "^3.0.2" - -is-npm@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" - integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== - -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-inside@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - -is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-plain-object@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== - -is-root@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" - integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== - -is-whitespace-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" - integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== - -is-word-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" - integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -is-yarn-global@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" - integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-worker@^27.4.5: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest-worker@^29.1.2: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" - integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== - dependencies: - "@types/node" "*" - jest-util "^29.7.0" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jiti@^1.18.2: - version "1.20.0" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.20.0.tgz#2d823b5852ee8963585c8dd8b7992ffc1ae83b42" - integrity sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA== - -joi@^17.6.0: - version "17.11.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.11.0.tgz#aa9da753578ec7720e6f0ca2c7046996ed04fc1a" - integrity sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ== - dependencies: - "@hapi/hoek" "^9.0.0" - "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.3" - "@sideway/formula" "^3.0.1" - "@sideway/pinpoint" "^2.0.0" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== - -json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json5@^2.1.2, json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -katex@^0.13.0: - version "0.13.24" - resolved "https://registry.yarnpkg.com/katex/-/katex-0.13.24.tgz#fe55455eb455698cb24b911a353d16a3c855d905" - integrity sha512-jZxYuKCma3VS5UuxOx/rFV1QyGSl3Uy/i0kTJF3HgQ5xMinCQVF8Zd4bMY/9aI9b9A2pjIBOsjSSm68ykTAr8w== - dependencies: - commander "^8.0.0" - -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - -khroma@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/khroma/-/khroma-2.1.0.tgz#45f2ce94ce231a437cf5b63c2e886e6eb42bbbb1" - integrity sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -latest-version@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" - integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== - dependencies: - package-json "^6.3.0" - -launch-editor@^2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.1.tgz#f259c9ef95cbc9425620bbbd14b468fcdb4ffe3c" - integrity sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw== - dependencies: - picocolors "^1.0.0" - shell-quote "^1.8.1" - -layout-base@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-1.0.2.tgz#1291e296883c322a9dd4c5dd82063721b53e26e2" - integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== - -layout-base@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-2.0.1.tgz#d0337913586c90f9c2c075292069f5c2da5dd285" - integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -lilconfig@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" - integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== - -loader-utils@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" - integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -loader-utils@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.1.tgz#4fb104b599daafd82ef3e1a41fb9265f87e1f576" - integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash-es@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" - integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== - -lodash.curry@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170" - integrity sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA== - -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== - -lodash.escape@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" - integrity sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw== - -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g== - -lodash.flow@^3.3.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" - integrity sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw== - -lodash.invokemap@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.invokemap/-/lodash.invokemap-4.6.0.tgz#1748cda5d8b0ef8369c4eb3ec54c21feba1f2d62" - integrity sha512-CfkycNtMqgUlfjfdh2BhKO/ZXrP8ePOX5lEU/g0R3ItJcnuxWDwokMGKx1hWcfOikmyOVx6X9IwWnDGlgKl61w== - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== - -lodash.pullall@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.pullall/-/lodash.pullall-4.2.0.tgz#9d98b8518b7c965b0fae4099bd9fb7df8bbf38ba" - integrity sha512-VhqxBKH0ZxPpLhiu68YD1KnHmbhQJQctcipvmFnqIBDYzcIHzf3Zpu0tpeOKtR4x76p9yohc506eGdOjTmyIBg== - -lodash.uniq@4.5.0, lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== - -lodash.uniqby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" - integrity sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww== - -lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -markdown-escapes@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" - integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== - -mdast-squeeze-paragraphs@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" - integrity sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ== - dependencies: - unist-util-remove "^2.0.0" - -mdast-util-definitions@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" - integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== - dependencies: - unist-util-visit "^2.0.0" - -mdast-util-from-markdown@^0.8.0: - version "0.8.5" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c" - integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-string "^2.0.0" - micromark "~2.11.0" - parse-entities "^2.0.0" - unist-util-stringify-position "^2.0.0" - -mdast-util-to-hast@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" - integrity sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - mdast-util-definitions "^4.0.0" - mdurl "^1.0.0" - unist-builder "^2.0.0" - unist-util-generated "^1.0.0" - unist-util-position "^3.0.0" - unist-util-visit "^2.0.0" - -mdast-util-to-hast@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz#61875526a017d8857b71abc9333942700b2d3604" - integrity sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - mdast-util-definitions "^4.0.0" - mdurl "^1.0.0" - unist-builder "^2.0.0" - unist-util-generated "^1.0.0" - unist-util-position "^3.0.0" - unist-util-visit "^2.0.0" - -mdast-util-to-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" - integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== - -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== - -mdurl@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -memfs@^3.1.2, memfs@^3.4.3: - version "3.6.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" - integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== - dependencies: - fs-monkey "^1.0.4" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -mermaid@^9.2.2: - version "9.4.3" - resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-9.4.3.tgz#62cf210c246b74972ea98c19837519b6f03427f2" - integrity sha512-TLkQEtqhRSuEHSE34lh5bCa94KATCyluAXmFnNI2PRZwOpXFeqiJWwZl+d2CcemE1RS6QbbueSSq9QIg8Uxcyw== - dependencies: - "@braintree/sanitize-url" "^6.0.0" - cytoscape "^3.23.0" - cytoscape-cose-bilkent "^4.1.0" - cytoscape-fcose "^2.1.0" - d3 "^7.4.0" - dagre-d3-es "7.0.9" - dayjs "^1.11.7" - dompurify "2.4.3" - elkjs "^0.8.2" - khroma "^2.0.0" - lodash-es "^4.17.21" - non-layered-tidy-tree-layout "^2.0.2" - stylis "^4.1.2" - ts-dedent "^2.2.0" - uuid "^9.0.0" - web-worker "^1.2.0" - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromark@~2.11.0: - version "2.11.4" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a" - integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== - dependencies: - debug "^4.0.0" - parse-entities "^2.0.0" - -micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-db@~1.33.0: - version "1.33.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" - integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== - -mime-types@2.1.18: - version "2.1.18" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" - integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== - dependencies: - mime-db "~1.33.0" - -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -mini-css-extract-plugin@^2.6.1: - version "2.7.6" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz#282a3d38863fddcd2e0c220aaed5b90bc156564d" - integrity sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw== - dependencies: - schema-utils "^4.0.0" - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.5: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mrmime@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" - integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - -nanoid@^3.3.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-emoji@^1.10.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" - integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== - dependencies: - lodash "^4.17.21" - -node-fetch@^2.6.12: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -node-forge@^1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== - -non-layered-tidy-tree-layout@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz#57d35d13c356643fc296a55fb11ac15e74da7804" - integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== - -normalize-url@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" - integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -nprogress@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" - integrity sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA== - -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" - -object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.0: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.9, open@^8.4.0: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -opener@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" - integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== - dependencies: - "@types/retry" "0.12.0" - retry "^0.13.1" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-json@^6.3.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" - integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== - dependencies: - got "^9.6.0" - registry-auth-token "^4.0.0" - registry-url "^5.0.0" - semver "^6.2.0" - -param-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" - integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" - integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-json@^5.0.0, parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse-numeric-range@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz#7c63b61190d61e4d53a1197f0c83c47bb670ffa3" - integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ== - -parse5-htmlparser2-tree-adapter@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" - integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== - dependencies: - domhandler "^5.0.2" - parse5 "^7.0.0" - -parse5@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -parse5@^7.0.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" - integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== - dependencies: - entities "^4.4.0" - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascal-case@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" - integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-is-inside@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - -path-to-regexp@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45" - integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== - -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pkg-up@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== - dependencies: - find-up "^3.0.0" - -postcss-calc@^8.2.3: - version "8.2.4" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" - integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== - dependencies: - postcss-selector-parser "^6.0.9" - postcss-value-parser "^4.2.0" - -postcss-colormin@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" - integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== - dependencies: - browserslist "^4.21.4" - caniuse-api "^3.0.0" - colord "^2.9.1" - postcss-value-parser "^4.2.0" - -postcss-convert-values@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" - integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== - dependencies: - browserslist "^4.21.4" - postcss-value-parser "^4.2.0" - -postcss-discard-comments@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" - integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== - -postcss-discard-duplicates@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" - integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== - -postcss-discard-empty@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" - integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== - -postcss-discard-overridden@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" - integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== - -postcss-discard-unused@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-5.1.0.tgz#8974e9b143d887677304e558c1166d3762501142" - integrity sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw== - dependencies: - postcss-selector-parser "^6.0.5" - -postcss-loader@^7.0.0: - version "7.3.3" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-7.3.3.tgz#6da03e71a918ef49df1bb4be4c80401df8e249dd" - integrity sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA== - dependencies: - cosmiconfig "^8.2.0" - jiti "^1.18.2" - semver "^7.3.8" - -postcss-merge-idents@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-5.1.1.tgz#7753817c2e0b75d0853b56f78a89771e15ca04a1" - integrity sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw== - dependencies: - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-merge-longhand@^5.1.7: - version "5.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" - integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== - dependencies: - postcss-value-parser "^4.2.0" - stylehacks "^5.1.1" - -postcss-merge-rules@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" - integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== - dependencies: - browserslist "^4.21.4" - caniuse-api "^3.0.0" - cssnano-utils "^3.1.0" - postcss-selector-parser "^6.0.5" - -postcss-minify-font-values@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" - integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-minify-gradients@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" - integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== - dependencies: - colord "^2.9.1" - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-minify-params@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" - integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== - dependencies: - browserslist "^4.21.4" - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-minify-selectors@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" - integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== - dependencies: - postcss-selector-parser "^6.0.5" - -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - -postcss-modules-local-by-default@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz#b08eb4f083050708998ba2c6061b50c2870ca524" - integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - -postcss-normalize-charset@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" - integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== - -postcss-normalize-display-values@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" - integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-positions@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" - integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-repeat-style@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" - integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-string@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" - integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-timing-functions@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" - integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-unicode@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" - integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== - dependencies: - browserslist "^4.21.4" - postcss-value-parser "^4.2.0" - -postcss-normalize-url@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" - integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== - dependencies: - normalize-url "^6.0.1" - postcss-value-parser "^4.2.0" - -postcss-normalize-whitespace@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" - integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-ordered-values@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" - integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== - dependencies: - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-reduce-idents@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz#c89c11336c432ac4b28792f24778859a67dfba95" - integrity sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-reduce-initial@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" - integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== - dependencies: - browserslist "^4.21.4" - caniuse-api "^3.0.0" - -postcss-reduce-transforms@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" - integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: - version "6.0.13" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" - integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-sort-media-queries@^4.2.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz#04a5a78db3921eb78f28a1a781a2e68e65258128" - integrity sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw== - dependencies: - sort-css-media-queries "2.1.0" - -postcss-svgo@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" - integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== - dependencies: - postcss-value-parser "^4.2.0" - svgo "^2.7.0" - -postcss-unique-selectors@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" - integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== - dependencies: - postcss-selector-parser "^6.0.5" - -postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss-zindex@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-5.1.0.tgz#4a5c7e5ff1050bd4c01d95b1847dfdcc58a496ff" - integrity sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A== - -postcss@^8.3.11, postcss@^8.4.14, postcss@^8.4.17, postcss@^8.4.21: - version "8.4.31" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" - integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== - dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== - -pretty-error@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" - integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== - dependencies: - lodash "^4.17.20" - renderkid "^3.0.0" - -pretty-time@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" - integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== - -prism-react-renderer@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz#786bb69aa6f73c32ba1ee813fbe17a0115435085" - integrity sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg== - -prismjs@^1.28.0: - version "1.29.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" - integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - -prompts@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -prop-types@^15.6.2, prop-types@^15.7.2: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - -property-information@^5.0.0, property-information@^5.3.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" - integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== - dependencies: - xtend "^4.0.0" - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^1.3.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -pupa@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" - integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== - dependencies: - escape-goat "^2.0.0" - -pure-color@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" - integrity sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA== - -qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -queue@6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" - integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== - dependencies: - inherits "~2.0.3" - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A== - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -rc@1.2.8, rc@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -react-base16-styling@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c" - integrity sha512-yvh/7CArceR/jNATXOKDlvTnPKPmGZz7zsenQ3jUwLzHkNUR0CvY3yGYJbWJ/nnxsL8Sgmt5cO3/SILVuPO6TQ== - dependencies: - base16 "^1.0.0" - lodash.curry "^4.0.1" - lodash.flow "^3.3.0" - pure-color "^1.2.0" - -react-dev-utils@^12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" - integrity sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ== - dependencies: - "@babel/code-frame" "^7.16.0" - address "^1.1.2" - browserslist "^4.18.1" - chalk "^4.1.2" - cross-spawn "^7.0.3" - detect-port-alt "^1.1.6" - escape-string-regexp "^4.0.0" - filesize "^8.0.6" - find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^6.5.0" - global-modules "^2.0.0" - globby "^11.0.4" - gzip-size "^6.0.0" - immer "^9.0.7" - is-root "^2.1.0" - loader-utils "^3.2.0" - open "^8.4.0" - pkg-up "^3.1.0" - prompts "^2.4.2" - react-error-overlay "^6.0.11" - recursive-readdir "^2.2.2" - shell-quote "^1.7.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -react-dom@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" - integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler "^0.20.2" - -react-error-overlay@^6.0.11: - version "6.0.11" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" - integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== - -react-fast-compare@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" - integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== - -react-helmet-async@*, react-helmet-async@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.3.0.tgz#7bd5bf8c5c69ea9f02f6083f14ce33ef545c222e" - integrity sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg== - dependencies: - "@babel/runtime" "^7.12.5" - invariant "^2.2.4" - prop-types "^15.7.2" - react-fast-compare "^3.2.0" - shallowequal "^1.1.0" - -react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-is@^17.0.0: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - -react-json-view@^1.21.3: - version "1.21.3" - resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475" - integrity sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw== - dependencies: - flux "^4.0.1" - react-base16-styling "^0.6.0" - react-lifecycles-compat "^3.0.4" - react-textarea-autosize "^8.3.2" - -react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - -react-loadable-ssr-addon-v5-slorber@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz#2cdc91e8a744ffdf9e3556caabeb6e4278689883" - integrity sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A== - dependencies: - "@babel/runtime" "^7.10.3" - -react-markdown@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-6.0.0.tgz#e63cd32d095e864384d524986c44c34c919de517" - integrity sha512-MC+zljUJeoLb4RbDm/wRbfoQFEZGz4TDOt/wb4dEehdaJWxLMn/T2IgwhQy0VYhuPEd2fhd7iOayE8lmENU0FA== - dependencies: - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.3" - comma-separated-tokens "^1.0.0" - prop-types "^15.7.2" - property-information "^5.0.0" - react-is "^17.0.0" - remark-parse "^9.0.0" - remark-rehype "^8.0.0" - space-separated-tokens "^1.1.0" - style-to-object "^0.3.0" - unified "^9.0.0" - unist-util-visit "^2.0.0" - -react-router-config@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988" - integrity sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg== - dependencies: - "@babel/runtime" "^7.1.2" - -react-router-dom@^5.3.3: - version "5.3.4" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.4.tgz#2ed62ffd88cae6db134445f4a0c0ae8b91d2e5e6" - integrity sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ== - dependencies: - "@babel/runtime" "^7.12.13" - history "^4.9.0" - loose-envify "^1.3.1" - prop-types "^15.6.2" - react-router "5.3.4" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - -react-router@5.3.4, react-router@^5.3.3: - version "5.3.4" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.4.tgz#8ca252d70fcc37841e31473c7a151cf777887bb5" - integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA== - dependencies: - "@babel/runtime" "^7.12.13" - history "^4.9.0" - hoist-non-react-statics "^3.1.0" - loose-envify "^1.3.1" - path-to-regexp "^1.7.0" - prop-types "^15.6.2" - react-is "^16.6.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - -react-textarea-autosize@^8.3.2: - version "8.5.3" - resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz#d1e9fe760178413891484847d3378706052dd409" - integrity sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ== - dependencies: - "@babel/runtime" "^7.20.13" - use-composed-ref "^1.3.0" - use-latest "^1.2.1" - -react@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -readable-stream@^2.0.1: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -reading-time@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/reading-time/-/reading-time-1.5.0.tgz#d2a7f1b6057cb2e169beaf87113cc3411b5bc5bb" - integrity sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg== - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== - dependencies: - resolve "^1.1.6" - -recursive-readdir@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" - integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== - dependencies: - minimatch "^3.0.5" - -regenerate-unicode-properties@^10.1.0: - version "10.1.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" - integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== - dependencies: - regenerate "^1.4.2" - -regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -regenerator-runtime@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" - integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== - -regenerator-transform@^0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" - integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== - dependencies: - "@babel/runtime" "^7.8.4" - -regexpu-core@^5.3.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" - integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== - dependencies: - "@babel/regjsgen" "^0.8.0" - regenerate "^1.4.2" - regenerate-unicode-properties "^10.1.0" - regjsparser "^0.9.1" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.1.0" - -registry-auth-token@^4.0.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.2.tgz#f02d49c3668884612ca031419491a13539e21fac" - integrity sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg== - dependencies: - rc "1.2.8" - -registry-url@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" - integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== - dependencies: - rc "^1.2.8" - -regjsparser@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" - integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== - dependencies: - jsesc "~0.5.0" - -rehype-katex@5: - version "5.0.0" - resolved "https://registry.yarnpkg.com/rehype-katex/-/rehype-katex-5.0.0.tgz#b556f24fde918f28ba1cb642ea71c7e82f3373d7" - integrity sha512-ksSuEKCql/IiIadOHiKRMjypva9BLhuwQNascMqaoGLDVd0k2NlE2wMvgZ3rpItzRKCd6vs8s7MFbb8pcR0AEg== - dependencies: - "@types/katex" "^0.11.0" - hast-util-to-text "^2.0.0" - katex "^0.13.0" - rehype-parse "^7.0.0" - unified "^9.0.0" - unist-util-visit "^2.0.0" - -rehype-parse@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-7.0.1.tgz#58900f6702b56767814afc2a9efa2d42b1c90c57" - integrity sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw== - dependencies: - hast-util-from-parse5 "^6.0.0" - parse5 "^6.0.0" - -relateurl@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== - -remark-emoji@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.2.0.tgz#1c702090a1525da5b80e15a8f963ef2c8236cac7" - integrity sha512-P3cj9s5ggsUvWw5fS2uzCHJMGuXYRb0NnZqYlNecewXt8QBU9n5vW3DUUKOhepS8F9CwdMx9B8a3i7pqFWAI5w== - dependencies: - emoticon "^3.2.0" - node-emoji "^1.10.0" - unist-util-visit "^2.0.3" - -remark-footnotes@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" - integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== - -remark-math@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/remark-math/-/remark-math-3.0.1.tgz#85a02a15b15cad34b89a27244d4887b3a95185bb" - integrity sha512-epT77R/HK0x7NqrWHdSV75uNLwn8g9qTyMqCRCDujL0vj/6T6+yhdrR7mjELWtkse+Fw02kijAaBuVcHBor1+Q== - -remark-mdx@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.22.tgz#06a8dab07dcfdd57f3373af7f86bd0e992108bbd" - integrity sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ== - dependencies: - "@babel/core" "7.12.9" - "@babel/helper-plugin-utils" "7.10.4" - "@babel/plugin-proposal-object-rest-spread" "7.12.1" - "@babel/plugin-syntax-jsx" "7.12.1" - "@mdx-js/util" "1.6.22" - is-alphabetical "1.0.4" - remark-parse "8.0.3" - unified "9.2.0" - -remark-parse@8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.3.tgz#9c62aa3b35b79a486454c690472906075f40c7e1" - integrity sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q== - dependencies: - ccount "^1.0.0" - collapse-white-space "^1.0.2" - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-whitespace-character "^1.0.0" - is-word-character "^1.0.0" - markdown-escapes "^1.0.0" - parse-entities "^2.0.0" - repeat-string "^1.5.4" - state-toggle "^1.0.0" - trim "0.0.1" - trim-trailing-lines "^1.0.0" - unherit "^1.0.4" - unist-util-remove-position "^2.0.0" - vfile-location "^3.0.0" - xtend "^4.0.1" - -remark-parse@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" - integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== - dependencies: - mdast-util-from-markdown "^0.8.0" - -remark-rehype@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-8.1.0.tgz#610509a043484c1e697437fa5eb3fd992617c945" - integrity sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA== - dependencies: - mdast-util-to-hast "^10.2.0" - -remark-squeeze-paragraphs@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" - integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== - dependencies: - mdast-squeeze-paragraphs "^4.0.0" - -renderkid@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" - integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== - dependencies: - css-select "^4.1.3" - dom-converter "^0.2.0" - htmlparser2 "^6.1.0" - lodash "^4.17.21" - strip-ansi "^6.0.1" - -repeat-string@^1.0.0, repeat-string@^1.5.4: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -"require-like@>= 0.1.1": - version "0.1.2" - resolved "https://registry.yarnpkg.com/require-like/-/require-like-0.1.2.tgz#ad6f30c13becd797010c468afa775c0c0a6b47fa" - integrity sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-pathname@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" - integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== - -resolve@^1.1.6, resolve@^1.14.2, resolve@^1.3.2: - version "1.22.6" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.6.tgz#dd209739eca3aef739c626fea1b4f3c506195362" - integrity sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== - dependencies: - lowercase-keys "^1.0.0" - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -robust-predicates@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771" - integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== - -rtl-detect@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/rtl-detect/-/rtl-detect-1.0.4.tgz#40ae0ea7302a150b96bc75af7d749607392ecac6" - integrity sha512-EBR4I2VDSSYr7PkBmFy04uhycIpDKp+21p/jARYXlCSjQksTBQcJ0HFUPOO79EPPH5JS6VAhiIQbycf0O3JAxQ== - -rtlcss@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-3.5.0.tgz#c9eb91269827a102bac7ae3115dd5d049de636c3" - integrity sha512-wzgMaMFHQTnyi9YOwsx9LjOxYXJPzS8sYnFaKm6R5ysvTkwzHiB0vxnbHwchHQT65PTdBjDG21/kQBWI7q9O7A== - dependencies: - find-up "^5.0.0" - picocolors "^1.0.0" - postcss "^8.3.11" - strip-json-comments "^3.1.1" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rw@1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" - integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== - -rxjs@^7.5.4: - version "7.8.1" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== - dependencies: - tslib "^2.1.0" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@^1.2.4: - version "1.3.0" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" - integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== - -scheduler@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" - integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== - dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" - -schema-utils@^2.6.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== - dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" - -schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" - integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.9.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.1.0" - -section-matter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" - integrity sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA== - dependencies: - extend-shallow "^2.0.1" - kind-of "^6.0.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== - -selfsigned@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" - integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== - dependencies: - node-forge "^1" - -semver-diff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" - integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== - dependencies: - semver "^6.3.0" - -semver@^5.4.1: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@^6.0.0, semver@^6.2.0, semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.3.2, semver@^7.3.4, semver@^7.3.7, semver@^7.3.8: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" - integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== - dependencies: - randombytes "^2.1.0" - -serve-handler@^6.1.3: - version "6.1.5" - resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.5.tgz#a4a0964f5c55c7e37a02a633232b6f0d6f068375" - integrity sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg== - dependencies: - bytes "3.0.0" - content-disposition "0.5.2" - fast-url-parser "1.1.3" - mime-types "2.1.18" - minimatch "3.1.2" - path-is-inside "1.0.2" - path-to-regexp "2.2.1" - range-parser "1.2.0" - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shallowequal@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" - integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shell-quote@^1.7.3, shell-quote@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" - integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== - -shelljs@^0.8.5: - version "0.8.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" - integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -sirv@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.3.tgz#ca5868b87205a74bef62a469ed0296abceccd446" - integrity sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA== - dependencies: - "@polka/url" "^1.0.0-next.20" - mrmime "^1.0.0" - totalist "^3.0.0" - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -sitemap@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/sitemap/-/sitemap-7.1.1.tgz#eeed9ad6d95499161a3eadc60f8c6dce4bea2bef" - integrity sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg== - dependencies: - "@types/node" "^17.0.5" - "@types/sax" "^1.2.1" - arg "^5.0.0" - sax "^1.2.4" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -sort-css-media-queries@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz#7c85e06f79826baabb232f5560e9745d7a78c4ce" - integrity sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA== - -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -space-separated-tokens@^1.0.0, space-separated-tokens@^1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" - integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - -state-toggle@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" - integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - -std-env@^3.0.1: - version "3.4.3" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.4.3.tgz#326f11db518db751c83fd58574f449b7c3060910" - integrity sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q== - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -stringify-object@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" - integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== - dependencies: - get-own-enumerable-property-symbols "^3.0.0" - is-obj "^1.0.1" - is-regexp "^1.0.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-bom-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" - integrity sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - -style-to-object@0.3.0, style-to-object@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" - integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== - dependencies: - inline-style-parser "0.1.1" - -stylehacks@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" - integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== - dependencies: - browserslist "^4.21.4" - postcss-selector-parser "^6.0.4" - -stylis@^4.1.2: - version "4.3.0" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.0.tgz#abe305a669fc3d8777e10eefcfc73ad861c5588c" - integrity sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ== - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -svg-parser@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" - integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== - -svgo@^2.7.0, svgo@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" - integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== - dependencies: - "@trysound/sax" "0.2.0" - commander "^7.2.0" - css-select "^4.1.3" - css-tree "^1.1.3" - csso "^4.2.0" - picocolors "^1.0.0" - stable "^0.1.8" - -tapable@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - -tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -terser-webpack-plugin@^5.3.3, terser-webpack-plugin@^5.3.7: - version "5.3.9" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" - integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.17" - jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.16.8" - -terser@^5.10.0, terser@^5.16.8: - version "5.21.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.21.0.tgz#d2b27e92b5e56650bc83b6defa00a110f0b124b2" - integrity sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" - commander "^2.20.0" - source-map-support "~0.5.20" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -tiny-invariant@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" - integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== - -tiny-warning@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" - integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -totalist@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" - integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -trim-trailing-lines@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" - integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== - -trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - integrity sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ== - -trough@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" - integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== - -ts-dedent@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" - integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== - -tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^2.5.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" - integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typescript@^4.7.4: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -ua-parser-js@^1.0.35: - version "1.0.36" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.36.tgz#a9ab6b9bd3a8efb90bb0816674b412717b7c428c" - integrity sha512-znuyCIXzl8ciS3+y3fHJI/2OhQIXbXw9MWC/o3qwyR+RGppjZHrM27CGFSKCJXi2Kctiz537iOu2KnXs1lMQhw== - -undici-types@~5.25.1: - version "5.25.3" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" - integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== - -unherit@^1.0.4: - version "1.1.3" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" - integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== - dependencies: - inherits "^2.0.0" - xtend "^4.0.0" - -unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" - integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== - -unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" - integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - -unicode-match-property-value-ecmascript@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" - integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== - -unicode-property-aliases-ecmascript@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" - integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== - -unified@9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8" - integrity sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - -unified@^9.0.0, unified@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" - integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== - dependencies: - crypto-random-string "^2.0.0" - -unist-builder@2.0.3, unist-builder@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" - integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== - -unist-util-find-after@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unist-util-find-after/-/unist-util-find-after-3.0.0.tgz#5c65fcebf64d4f8f496db46fa8fd0fbf354b43e6" - integrity sha512-ojlBqfsBftYXExNu3+hHLfJQ/X1jYY/9vdm4yZWjIbf0VuWF6CRufci1ZyoD/wV2TYMKxXUoNuoqwy+CkgzAiQ== - dependencies: - unist-util-is "^4.0.0" - -unist-util-generated@^1.0.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" - integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== - -unist-util-is@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" - integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== - -unist-util-position@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" - integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== - -unist-util-remove-position@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" - integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== - dependencies: - unist-util-visit "^2.0.0" - -unist-util-remove@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" - integrity sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q== - dependencies: - unist-util-is "^4.0.0" - -unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== - dependencies: - "@types/unist" "^2.0.2" - -unist-util-visit-parents@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" - integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - -unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" - integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -update-notifier@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" - integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== - dependencies: - boxen "^5.0.0" - chalk "^4.1.0" - configstore "^5.0.1" - has-yarn "^2.1.0" - import-lazy "^2.1.0" - is-ci "^2.0.0" - is-installed-globally "^0.4.0" - is-npm "^5.0.0" - is-yarn-global "^0.3.0" - latest-version "^5.1.0" - pupa "^2.1.1" - semver "^7.3.4" - semver-diff "^3.1.1" - xdg-basedir "^4.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" - integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== - dependencies: - prepend-http "^2.0.0" - -use-composed-ref@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda" - integrity sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ== - -use-isomorphic-layout-effect@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" - integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== - -use-latest@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.1.tgz#d13dfb4b08c28e3e33991546a2cee53e14038cf2" - integrity sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw== - dependencies: - use-isomorphic-layout-effect "^1.1.1" - -use-sync-external-store@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -utila@~0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== - -utility-types@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" - integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -uuid@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - -value-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" - integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -vfile-location@^3.0.0, vfile-location@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" - integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== - -vfile-message@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" - integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^2.0.0" - -vfile@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" - integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" - -wait-on@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.1.tgz#16bbc4d1e4ebdd41c5b4e63a2e16dbd1f4e5601e" - integrity sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw== - dependencies: - axios "^0.25.0" - joi "^17.6.0" - lodash "^4.17.21" - minimist "^1.2.5" - rxjs "^7.5.4" - -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -web-namespaces@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" - integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== - -web-worker@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.2.0.tgz#5d85a04a7fbc1e7db58f66595d7a3ac7c9c180da" - integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -webpack-bundle-analyzer@^4.5.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.9.1.tgz#d00bbf3f17500c10985084f22f1a2bf45cb2f09d" - integrity sha512-jnd6EoYrf9yMxCyYDPj8eutJvtjQNp8PHmni/e/ulydHBWhT5J3menXt3HEkScsu9YqMAcG4CfFjs3rj5pVU1w== - dependencies: - "@discoveryjs/json-ext" "0.5.7" - acorn "^8.0.4" - acorn-walk "^8.0.0" - commander "^7.2.0" - escape-string-regexp "^4.0.0" - gzip-size "^6.0.0" - is-plain-object "^5.0.0" - lodash.debounce "^4.0.8" - lodash.escape "^4.0.1" - lodash.flatten "^4.4.0" - lodash.invokemap "^4.6.0" - lodash.pullall "^4.2.0" - lodash.uniqby "^4.7.0" - opener "^1.5.2" - picocolors "^1.0.0" - sirv "^2.0.3" - ws "^7.3.1" - -webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@^4.9.3: - version "4.15.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz#8944b29c12760b3a45bdaa70799b17cb91b03df7" - integrity sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.5" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - launch-editor "^2.6.0" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.13.0" - -webpack-merge@^5.8.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.9.0.tgz#dc160a1c4cf512ceca515cc231669e9ddb133826" - integrity sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - -webpack-sources@^3.2.2, webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== - -webpack@^5.73.0: - version "5.88.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" - integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.0" - "@webassemblyjs/ast" "^1.11.5" - "@webassemblyjs/wasm-edit" "^1.11.5" - "@webassemblyjs/wasm-parser" "^1.11.5" - acorn "^8.7.1" - acorn-import-assertions "^1.9.0" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.15.0" - es-module-lexer "^1.2.1" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.2.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.7" - watchpack "^2.4.0" - webpack-sources "^3.2.3" - -webpackbar@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-5.0.2.tgz#d3dd466211c73852741dfc842b7556dcbc2b0570" - integrity sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ== - dependencies: - chalk "^4.1.0" - consola "^2.15.3" - pretty-time "^1.1.0" - std-env "^3.0.1" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -widest-line@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2" - integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig== - dependencies: - string-width "^5.0.1" - -wildcard@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" - integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.0.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -ws@^7.3.1: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -ws@^8.13.0: - version "8.14.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" - integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== - -xdg-basedir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" - integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== - -xml-js@^1.6.11: - version "1.6.11" - resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" - integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g== - dependencies: - sax "^1.2.4" - -xtend@^4.0.0, xtend@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zwitch@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==