diff --git a/.dockerignore b/.dockerignore index 39efdabca19a..528c0ed9793a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -20,11 +20,12 @@ keys/setup !prover/ !yarn.lock !package.json -!Cargo.lock -!Cargo.toml +!core/Cargo.lock +!core/Cargo.toml !contracts/ !setup_2\^26.key !setup_2\^24.key +!setup_compact.key # It's required to remove .git from contracts, # otherwise yarn tries to use .git parent directory that # doesn't exist. diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 1f0c6b945b65..df99db16605f 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -15,8 +15,6 @@ check_fmt () { fi } -check_fmt - -cd prover/ - -check_fmt +( cd core/ && check_fmt ) +( cd prover/ && check_fmt ) +( cd zkstack_cli/ && check_fmt ) diff --git a/.github/release-please/config.json b/.github/release-please/config.json index 358e249a18bd..28c3583af29e 100644 --- a/.github/release-please/config.json +++ b/.github/release-please/config.json @@ -5,26 +5,27 @@ "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, "include-component-in-tag": true, + "release-type": "simple", "packages": { "core": { - "release-type": "simple", - "component": "core", + "component": "core" + }, + "prover": { + "component": "prover", "extra-files": [ { "type": "generic", - "path": "bin/external_node/Cargo.toml" + "path": "Cargo.toml" } ] }, - "prover": { - "release-type": "simple", - "component": "prover" - }, "zkstack_cli": { - "release-type": "simple", "component": "zkstack_cli", - "plugins": [ - "cargo-workspace" + "extra-files": [ + { + "type": "generic", + "path": "Cargo.toml" + } ] } } diff --git a/.github/release-please/manifest.json b/.github/release-please/manifest.json index c43a992917e1..c64c1f4ecc4f 100644 --- a/.github/release-please/manifest.json +++ b/.github/release-please/manifest.json @@ -1,5 +1,5 @@ { - "core": "25.4.0", - "prover": "17.1.1", + "core": "26.2.1", + "prover": "18.0.0", "zkstack_cli": "0.1.2" } diff --git a/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml b/.github/workflows/build-circuit-prover-gpu-gar.yml similarity index 67% rename from .github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml rename to .github/workflows/build-circuit-prover-gpu-gar.yml index 30990889caf6..a8e86d545c9f 100644 --- a/.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml +++ b/.github/workflows/build-circuit-prover-gpu-gar.yml @@ -27,7 +27,7 @@ jobs: - name: Download Setup data run: | - gsutil -m rsync -r gs://matterlabs-setup-data-us/${{ inputs.setup_keys_id }} docker/prover-gpu-fri-gar + gsutil -m rsync -r gs://matterlabs-setup-data-us/${{ inputs.setup_keys_id }} docker/circuit-prover-gpu-gar - name: Login to us-central1 GAR run: | @@ -47,32 +47,6 @@ jobs: run: | gcloud auth print-access-token --lifetime=7200 --impersonate-service-account=gha-ci-runners@matterlabs-infra.iam.gserviceaccount.com | docker login -u oauth2accesstoken --password-stdin https://europe-docker.pkg.dev - - name: Build and push prover-gpu-fri-gar - uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 - with: - context: docker/prover-gpu-fri-gar - build-args: | - PROVER_IMAGE=${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} - push: true - tags: | - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} - - - name: Build and push prover-gpu-fri-gar to Asia GAR - run: | - docker buildx imagetools create \ - --tag asia-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} \ - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} - - - name: Build and push prover-gpu-fri-gar to Europe GAR - run: | - docker buildx imagetools create \ - --tag europe-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} \ - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/prover-fri-gpu-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} - - - name: Move Setup data from prover-gpu-fri-gar to circuit-prover-gpu-gar - run: | - mv -v docker/prover-gpu-fri-gar/*.bin docker/circuit-prover-gpu-gar/ - - name: Build and push circuit-prover-gpu-gar uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: diff --git a/.github/workflows/build-docker-from-tag.yml b/.github/workflows/build-docker-from-tag.yml index 34f4b55903d2..3d637a224a99 100644 --- a/.github/workflows/build-docker-from-tag.yml +++ b/.github/workflows/build-docker-from-tag.yml @@ -110,10 +110,10 @@ jobs: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - build-gar-prover-fri-gpu-and-circuit-prover-gpu-gar: + build-circuit-prover-gpu-gar: name: Build GAR prover FRI GPU needs: [setup, build-push-prover-images] - uses: ./.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml + uses: ./.github/workflows/build-circuit-prover-gpu-gar.yml if: contains(github.ref_name, 'prover') with: setup_keys_id: ${{ needs.setup.outputs.prover_fri_gpu_key_id }} diff --git a/.github/workflows/build-proof-fri-gpu-compressor-gar.yml b/.github/workflows/build-proof-fri-gpu-compressor-gar.yml index e11a49640369..aeaaf5ff190d 100644 --- a/.github/workflows/build-proof-fri-gpu-compressor-gar.yml +++ b/.github/workflows/build-proof-fri-gpu-compressor-gar.yml @@ -28,7 +28,7 @@ jobs: - name: Download FFLONK key and setup data run: | gsutil -m rsync -r gs://matterlabs-setup-data-us/${{ inputs.setup_keys_id }} docker/proof-fri-gpu-compressor-gar - gsutil -m cp -r gs://matterlabs-setup-keys-us/setup-keys/setup_fflonk_compact.key docker/proof-fri-gpu-compressor-gar + gsutil -m cp -r gs://matterlabs-setup-keys-us/setup-keys/setup_compact.key docker/proof-fri-gpu-compressor-gar - name: Login to us-central1 GAR run: | @@ -58,13 +58,13 @@ jobs: tags: | us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/proof-fri-gpu-compressor-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} - - name: Build and push prover-gpu-fri-gar to Asia GAR + - name: Build and push proof-fri-gpu-compressor-gar to Asia GAR run: | docker buildx imagetools create \ --tag asia-docker.pkg.dev/matterlabs-infra/matterlabs-docker/proof-fri-gpu-compressor-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} \ us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/proof-fri-gpu-compressor-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} - - name: Build and push prover-gpu-fri-gar to Europe GAR + - name: Build and push proof-fri-gpu-compressor-gar to Europe GAR run: | docker buildx imagetools create \ --tag europe-docker.pkg.dev/matterlabs-infra/matterlabs-docker/proof-fri-gpu-compressor-gar:2.0-${{ inputs.protocol_version }}-${{ inputs.image_tag_suffix }} \ diff --git a/.github/workflows/build-prover-template.yml b/.github/workflows/build-prover-template.yml index 7d2920a2af4e..dc097b240b70 100644 --- a/.github/workflows/build-prover-template.yml +++ b/.github/workflows/build-prover-template.yml @@ -98,8 +98,6 @@ jobs: matrix: components: - witness-generator - - prover-gpu-fri - - witness-vector-generator - prover-fri-gateway - prover-job-monitor - proof-fri-gpu-compressor @@ -201,42 +199,3 @@ jobs: docker push us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:latest docker push ghcr.io/${{ github.repository_owner }}/${{ matrix.components }}:latest docker push matterlabs/${{ matrix.components }}:latest - - copy-images: - name: Copy images between docker registries - needs: [build-images, get-protocol-version] - env: - PROTOCOL_VERSION: ${{ needs.get-protocol-version.outputs.protocol_version }} - runs-on: matterlabs-ci-runner - if: ${{ inputs.action == 'push' }} - strategy: - matrix: - component: - - witness-vector-generator - steps: - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1 - - - name: Login to us-central1 GAR - run: | - gcloud auth print-access-token --lifetime=7200 --impersonate-service-account=gha-ci-runners@matterlabs-infra.iam.gserviceaccount.com | docker login -u oauth2accesstoken --password-stdin https://us-docker.pkg.dev - - - name: Login and push to Asia GAR - run: | - gcloud auth print-access-token --lifetime=7200 --impersonate-service-account=gha-ci-runners@matterlabs-infra.iam.gserviceaccount.com | docker login -u oauth2accesstoken --password-stdin https://asia-docker.pkg.dev - docker buildx imagetools create \ - --tag asia-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.component }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ inputs.image_tag_suffix }} \ - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.component }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ inputs.image_tag_suffix }} - docker buildx imagetools create \ - --tag asia-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.component }}:2.0-${{ inputs.image_tag_suffix }} \ - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.component }}:2.0-${{ inputs.image_tag_suffix }} - - - name: Login and push to Europe GAR - run: | - gcloud auth print-access-token --lifetime=7200 --impersonate-service-account=gha-ci-runners@matterlabs-infra.iam.gserviceaccount.com | docker login -u oauth2accesstoken --password-stdin https://europe-docker.pkg.dev - docker buildx imagetools create \ - --tag europe-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.component }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ inputs.image_tag_suffix }} \ - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.component }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ inputs.image_tag_suffix }} - docker buildx imagetools create \ - --tag europe-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.component }}:2.0-${{ inputs.image_tag_suffix }} \ - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.component }}:2.0-${{ inputs.image_tag_suffix }} diff --git a/.github/workflows/cargo-license.yaml b/.github/workflows/cargo-license.yaml index 72eb8d0d865b..8b0c095c628c 100644 --- a/.github/workflows/cargo-license.yaml +++ b/.github/workflows/cargo-license.yaml @@ -7,5 +7,6 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - uses: EmbarkStudios/cargo-deny-action@8371184bd11e21dcf8ac82ebf8c9c9f74ebf7268 # v2.0.1 with: + manifest-path: "./core/Cargo.toml" command: check command-arguments: "--hide-inclusion-graph" diff --git a/.github/workflows/ci-core-reusable.yml b/.github/workflows/ci-core-reusable.yml index 25a0da838f42..3a399cc8f738 100644 --- a/.github/workflows/ci-core-reusable.yml +++ b/.github/workflows/ci-core-reusable.yml @@ -72,14 +72,14 @@ jobs: ci_run zkstack dev contracts - name: Download compilers for contract verifier tests - run: ci_run zkstack contract-verifier init --zksolc-version=v1.5.3 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era + run: ci_run zkstack contract-verifier init --zksolc-version=v1.5.10 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era - name: Rust unit tests run: | ci_run zkstack dev test rust # Benchmarks are not tested by `cargo nextest` unless specified explicitly, and even then `criterion` harness is incompatible # with how `cargo nextest` runs tests. Thus, we run criterion-based benchmark tests manually. - ci_run cargo test --release -p vm-benchmark --bench oneshot --bench batch + ci_run cargo test --manifest-path ./core/Cargo.toml --release -p vm-benchmark --bench oneshot --bench batch loadtest: runs-on: [ matterlabs-ci-runner-high-performance ] @@ -431,7 +431,7 @@ jobs: - name: Initialize Contract verifier run: | - ci_run zkstack contract-verifier init --zksolc-version=v1.5.3 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era + ci_run zkstack contract-verifier init --zksolc-version=v1.5.10 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era ci_run zkstack contract-verifier run --chain era &> ${{ env.SERVER_LOGS_DIR }}/contract-verifier-rollup.log & ci_run zkstack contract-verifier wait --chain era --verbose @@ -456,12 +456,21 @@ jobs: - name: Set up attester committee for the consensus chain run: | ci_run zkstack consensus wait-for-registry --ignore-prerequisites --verbose --chain consensus - ci_run zkstack consensus set-attester-committee --chain consensus --from-genesis &> ${{ env.INTEGRATION_TESTS_LOGS_DIR }}/consensus.log + ci_run zkstack consensus set-attester-committee --chain consensus --ignore-prerequisites --verbose --from-genesis &> ${{ env.INTEGRATION_TESTS_LOGS_DIR }}/consensus.log - name: Run integration tests run: | ci_run ./bin/run_on_all_chains.sh "zkstack dev test integration --no-deps --ignore-prerequisites" ${{ env.CHAINS }} ${{ env.INTEGRATION_TESTS_LOGS_DIR }} + - name: Repeat integration tests on push to main to check for flakiness + if: ${{ (steps.condition.outputs.should_run == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main') }} + run: | + for i in {1..10}; do + echo "Iteration $i" + mkdir -p ${{ env.INTEGRATION_TESTS_LOGS_DIR }}/$i + ci_run ./bin/run_on_all_chains.sh "zkstack dev test integration --no-deps --ignore-prerequisites" ${{ env.CHAINS }} ${{ env.INTEGRATION_TESTS_LOGS_DIR }}/$i + done + - name: Init external nodes run: | GATEWAY_RPC_URL="${{ matrix.use_gateway_chain == 'WITH_GATEWAY' && '--gateway-rpc-url=http://localhost:3550' || '' }}" @@ -506,6 +515,15 @@ jobs: run: | ci_run ./bin/run_on_all_chains.sh "zkstack dev test integration --no-deps --ignore-prerequisites --external-node" ${{ env.CHAINS }} ${{ env.INTEGRATION_TESTS_LOGS_DIR }} + - name: Repeat integration tests en on push to main to check for flakiness + if: ${{ (steps.condition.outputs.should_run == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main') }} + run: | + for i in {1..10}; do + echo "Iteration $i" + mkdir -p ${{ env.INTEGRATION_TESTS_LOGS_DIR }}/$i + ci_run ./bin/run_on_all_chains.sh "zkstack dev test integration --no-deps --ignore-prerequisites --external-node" ${{ env.CHAINS }} ${{ env.INTEGRATION_TESTS_LOGS_DIR }}/$i + done + - name: Fee projection tests run: | ci_run killall -INT zksync_server || true @@ -519,6 +537,15 @@ jobs: # Always run the chain-specific fee tests ci_run ./bin/run_on_all_chains.sh "zkstack dev test fees --no-deps --no-kill" ${{ env.CHAINS }} ${{ env.FEES_LOGS_DIR }} + - name: Repeat fee projection tests on push to main to check for flakiness + if: ${{ (steps.condition.outputs.should_run == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main') }} + run: | + for i in {1..10}; do + echo "Iteration $i" + mkdir -p ${{ env.FEES_LOGS_DIR }}/$i + ci_run ./bin/run_on_all_chains.sh "zkstack dev test fees --no-deps --no-kill" ${{ env.CHAINS }} ${{ env.FEES_LOGS_DIR }}/$i + done + - name: Run revert tests run: | ci_run killall -INT zksync_server || true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 899eaea4b445..a0b7ee1bc40e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,8 +57,8 @@ jobs: - '.github/workflows/build-contract-verifier-template.yml' - '.github/workflows/ci-core-reusable.yml' - '.github/workflows/ci-core-lint-reusable.yml' - - 'Cargo.toml' - - 'Cargo.lock' + - './core/Cargo.toml' + - './core/Cargo.lock' - 'zkstack_cli/**' - '!**/*.md' - '!**/*.MD' diff --git a/.github/workflows/protobuf.yaml b/.github/workflows/protobuf.yaml index f0565919ded1..62748c79251a 100644 --- a/.github/workflows/protobuf.yaml +++ b/.github/workflows/protobuf.yaml @@ -31,7 +31,7 @@ env: jobs: compatibility: - runs-on: [ubuntu-22.04-github-hosted-16core] + runs-on: [ubuntu-24.04-github-hosted-16core] steps: - uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af # v0.0.5 @@ -46,13 +46,15 @@ jobs: run: git checkout $(git merge-base $BASE $HEAD) --recurse-submodules working-directory: ./before + - name: compile before - run: cargo check --all-targets - working-directory: ./before/ + run: cargo check --manifest-path ./core/Cargo.toml --all-targets + working-directory: ./before + - name: build before.binpb run: > perl -ne 'print "$1\n" if /PROTOBUF_DESCRIPTOR="(.*)"/' - `find ./before/target/debug/build/*/output` + `find ./before/core/target/debug/build/*/output` | xargs cat > ./before.binpb # after @@ -61,13 +63,15 @@ jobs: ref: ${{ env.HEAD }} path: after submodules: recursive + - name: compile after - run: cargo check --all-targets + run: cargo check --manifest-path ./core/Cargo.toml --all-targets working-directory: ./after + - name: build after.binpb run: > perl -ne 'print "$1\n" if /PROTOBUF_DESCRIPTOR="(.*)"/' - `find ./after/target/debug/build/*/output` + `find ./after/core/target/debug/build/*/output` | xargs cat > ./after.binpb # compare @@ -75,6 +79,8 @@ jobs: with: github_token: ${{ github.token }} - name: buf breaking - run: > - buf breaking './after.binpb' --against './before.binpb' --exclude-path 'zksync/config/experimental.proto' - --config '{"version":"v1","breaking":{"use":["WIRE_JSON","WIRE"]}}' --error-format 'github-actions' + run: | + pwd + ls -la + buf breaking './after.binpb' --against './before.binpb' --exclude-path 'zksync/config/experimental.proto' \ + --config '{"version":"v1","breaking":{"use":["WIRE_JSON","WIRE"]}}' --error-format 'github-actions' diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml new file mode 100644 index 000000000000..ebfb96a544c8 --- /dev/null +++ b/.github/workflows/publish-crates.yml @@ -0,0 +1,42 @@ +name: Publish crates + +on: + workflow_dispatch: + inputs: + component: + description: 'Component to release. Possible values are: core, prover or zkstack_cli.' + required: true + default: 'zkstack_cli' + run-build: + type: boolean + description: 'Build the workspace before release.' + required: false + default: true + run-tests: + type: boolean + description: 'Run tests before release.' + required: false + default: false + org-owner: + type: string + description: 'Organization to add as owner of the crates.' + required: false + default: 'github:matter-labs:crates-io' + + +jobs: + + publish-crates: + name: Publish to crates.io + runs-on: matterlabs-ci-runner-high-performance + steps: + - name: Publish crates + uses: matter-labs/zksync-ci-common/.github/actions/publish-crates@v1 + with: + slack_webhook: ${{ secrets.SLACK_WEBHOOK_RELEASES }} # Slack webhook for notifications + cargo_registry_token: ${{ secrets.CRATES_IO_TOKEN }} # Crates.io token for publishing + workspace_path: ${{ inputs.component }} + org_owner: ${{ inputs.org-owner }} + run_build: ${{ inputs.run-build }} + run_tests: ${{ inputs.run-tests }} + gh_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-please-cargo-lock.yml b/.github/workflows/release-please-cargo-lock.yml deleted file mode 100644 index 8c8036dfa47a..000000000000 --- a/.github/workflows/release-please-cargo-lock.yml +++ /dev/null @@ -1,55 +0,0 @@ -on: - push: - branches: - - release-please--branches--main--components--core - -name: release-please-update-cargo-lock -jobs: - update_cargo_lock: - # TODO: After migraton switch to CI - runs-on: [matterlabs-default-infra-runners] - - steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 - with: - submodules: "recursive" - persist-credentials: false - - - name: Check last commit - id: condition - run: | - COMMIT=$(git log -1 --pretty=%B) - if [[ "$COMMIT" == "Update Cargo.lock" ]]; then - echo "Cargo.lock is already updated" - echo "::set-output name=skip_steps::true" - else - echo "Cargo.lock should be updated" - echo "::set-output name=skip_steps::false" - fi - - - name: Setup environment - if: steps.condition.outputs.skip_steps != 'true' - run: | - echo ZKSYNC_HOME=$(pwd) >> $GITHUB_ENV - echo $(pwd)/bin >> $GITHUB_PATH - echo IN_DOCKER=1 >> .env - - - name: Start services - if: steps.condition.outputs.skip_steps != 'true' - run: docker compose up -d zk - - - name: Cargo check - if: steps.condition.outputs.skip_steps != 'true' - run: ci_run cargo check - - - name: Push changes - if: steps.condition.outputs.skip_steps != 'true' - env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} - run: | - git config --global user.email "zksync-era-bot@users.noreply.github.com" - git config --global user.name "zksync-era-bot" - git remote set-url origin 'https://${{ secrets.RELEASE_TOKEN }}@github.com/matter-labs/zksync-era.git' - git add ./Cargo.lock - git commit -m "Update Cargo.lock" - git push diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 4a8f527f45c6..6a3935e9da84 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -1,29 +1,32 @@ +name: Release-please + +# Give permissions to the release-please to open, update PRs +# and commit to PRs the repository to update Cargo.lock +permissions: + contents: write + pull-requests: write + id-token: write + attestations: write + +# Run the workflow on push to the main branch or manually on: push: branches: - main workflow_dispatch: -permissions: - contents: write - pull-requests: write - -name: release-please jobs: - release-please: - runs-on: ubuntu-latest - steps: - - name: Run release-please - id: release - uses: google-github-actions/release-please-action@e4dc86ba9405554aeba3c6bb2d169500e7d3b4ee # v4.1.1 - with: - token: ${{ secrets.RELEASE_TOKEN }} - config-file: .github/release-please/config.json - manifest-file: .github/release-please/manifest.json - - name: Send Release Info - if: ${{ steps.release.outputs.releases_created == 'true' }} - uses: matter-labs/format-release-please-for-slack-action@69e6fe9e4ec531b7b5fb0d826f73c190db83cf42 # v2.1.0 - with: - release-please-output: ${{ toJSON(steps.release.outputs) }} - slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_RELEASES }} + # Prepare the release PR with changelog updates and create github releases + release-please: + uses: matter-labs/zksync-ci-common/.github/workflows/release-please.yaml@v1 + secrets: + slack_webhook: ${{ secrets.SLACK_WEBHOOK_RELEASES }} # Slack webhook for notifications + gh_token: ${{ secrets.RELEASE_TOKEN }} # GitHub token for release-please + with: + config: '.github/release-please/config.json' # Path to the configuration file + manifest: '.github/release-please/manifest.json' # Path to the manifest file + update-cargo-lock: true # Update Cargo.lock file in the release PR + publish-to-crates-io: true # Enable publishing to crates.io + upgrade-dependencies: true # Upgrade cross-workspace dependencies + version-suffix: 'non-semver-compat' # Version suffix for the crates.io release diff --git a/.github/workflows/release-test-stage.yml b/.github/workflows/release-test-stage.yml index afd33979234d..cff6c5ee0b3f 100644 --- a/.github/workflows/release-test-stage.yml +++ b/.github/workflows/release-test-stage.yml @@ -121,10 +121,10 @@ jobs: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - build-gar-prover-fri-gpu-and-circuit-prover-gpu-gar: + build-circuit-prover-gpu-gar: name: Build GAR prover FRI GPU needs: [setup, build-push-prover-images] - uses: ./.github/workflows/build-prover-fri-gpu-gar-and-circuit-prover-gpu-gar.yml + uses: ./.github/workflows/build-circuit-prover-gpu-gar.yml if: needs.changed_files.outputs.prover == 'true' || needs.changed_files.outputs.all == 'true' with: setup_keys_id: ${{ needs.setup.outputs.prover_fri_gpu_key_id }} diff --git a/.github/workflows/vm-perf-comparison.yml b/.github/workflows/vm-perf-comparison.yml index ac83485a2c12..223404fa0b4f 100644 --- a/.github/workflows/vm-perf-comparison.yml +++ b/.github/workflows/vm-perf-comparison.yml @@ -53,8 +53,10 @@ jobs: run: | ci_run zkstackup -g --local ci_run zkstack dev contracts - ci_run cargo bench --package vm-benchmark --bench instructions -- --verbose || echo "Instructions benchmark is missing" - ci_run cargo run --package vm-benchmark --release --bin instruction_counts | tee base-opcodes + ci_run cargo bench --manifest-path ./core/Cargo.toml \ + --package vm-benchmark --bench instructions -- --verbose || echo "Instructions benchmark is missing" + ci_run cargo run --manifest-path ./core/Cargo.toml \ + --package vm-benchmark --release --bin instruction_counts | tee base-opcodes - name: checkout PR run: | @@ -67,9 +69,10 @@ jobs: run: | ci_run zkstackup -g --local ci_run zkstack dev contracts - ci_run cargo bench --package vm-benchmark --bench instructions -- --verbose + ci_run cargo bench --manifest-path ./core/Cargo.toml --package vm-benchmark --bench instructions -- --verbose - ci_run cargo bench --package vm-benchmark --bench instructions -- --print > instructions.log 2>/dev/null + ci_run cargo bench --manifest-path ./core/Cargo.toml \ + --package vm-benchmark --bench instructions -- --print > instructions.log 2>/dev/null # Output all lines from the benchmark result starting from the "## ..." comparison header. # Since the output spans multiple lines, we use a heredoc declaration. EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) @@ -77,7 +80,8 @@ jobs: sed -n '/^## /,$p' instructions.log >> $GITHUB_OUTPUT echo "$EOF" >> $GITHUB_OUTPUT - ci_run cargo run --package vm-benchmark --release --bin instruction_counts -- --diff base-opcodes > opcodes.log + ci_run cargo run --manifest-path ./core/Cargo.toml \ + --package vm-benchmark --release --bin instruction_counts -- --diff base-opcodes > opcodes.log echo "opcodes<<$EOF" >> $GITHUB_OUTPUT sed -n '/^## /,$p' opcodes.log >> $GITHUB_OUTPUT echo "$EOF" >> $GITHUB_OUTPUT diff --git a/.github/workflows/vm-perf-to-prometheus.yml b/.github/workflows/vm-perf-to-prometheus.yml index 93d33116794f..0868e0902342 100644 --- a/.github/workflows/vm-perf-to-prometheus.yml +++ b/.github/workflows/vm-perf-to-prometheus.yml @@ -45,8 +45,8 @@ jobs: - name: run benchmarks run: | - ci_run cargo bench --package vm-benchmark --bench oneshot + ci_run cargo bench --manifest-path ./core/Cargo.toml --package vm-benchmark --bench oneshot # Run only benches with 1,000 transactions per batch to not spend too much time - ci_run cargo bench --package vm-benchmark --bench batch '/1000$' - ci_run cargo bench --package vm-benchmark --bench instructions -- --verbose - ci_run cargo bench --package vm-benchmark --bench instructions -- --print + ci_run cargo bench --manifest-path ./core/Cargo.toml --package vm-benchmark --bench batch '/1000$' + ci_run cargo bench --manifest-path ./core/Cargo.toml --package vm-benchmark --bench instructions -- --verbose + ci_run cargo bench --manifest-path ./core/Cargo.toml --package vm-benchmark --bench instructions -- --print diff --git a/.gitignore b/.gitignore index 471a601cc34b..716024531d4a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,12 +26,6 @@ zksync_pk.key dist todo -Cargo.lock -!/Cargo.lock -!/infrastructure/zksync-crypto/Cargo.lock -!/prover/Cargo.lock -!/zkstack_cli/Cargo.lock - /etc/env/target/* /etc/env/.current /etc/env/configs/* @@ -111,6 +105,8 @@ hyperchain-*.yml # Prover keys that should not be commited prover/crates/bin/vk_setup_data_generator_server_fri/data/setup_* prover/data/keys/setup_* +prover/data/keys/fflonk_setup_snark_data.bin +prover/data/keys/plonk_setup_snark_data.bin # ZK Stack CLI chains/era/configs/* diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 21a1a342f1ab..000000000000 --- a/Cargo.toml +++ /dev/null @@ -1,326 +0,0 @@ -[workspace] -members = [ - # Binaries - "core/bin/block_reverter", - "core/bin/contract-verifier", - "core/bin/custom_genesis_export", - "core/bin/external_node", - "core/bin/merkle_tree_consistency_checker", - "core/bin/snapshots_creator", - "core/bin/selector_generator", - "core/bin/system-constants-generator", - "core/bin/verified_sources_fetcher", - "core/bin/zksync_server", - "core/bin/genesis_generator", - "core/bin/zksync_tee_prover", - # Node services - "core/node/node_framework", - "core/node/proof_data_handler", - "core/node/block_reverter", - "core/node/commitment_generator", - "core/node/house_keeper", - "core/node/genesis", - "core/node/shared_metrics", - "core/node/db_pruner", - "core/node/fee_model", - "core/node/da_dispatcher", - "core/node/eth_sender", - "core/node/vm_runner", - "core/node/test_utils", - "core/node/state_keeper", - "core/node/reorg_detector", - "core/node/consistency_checker", - "core/node/metadata_calculator", - "core/node/node_sync", - "core/node/node_storage_init", - "core/node/consensus", - "core/node/contract_verification_server", - "core/node/api_server", - "core/node/base_token_adjuster", - "core/node/external_proof_integration_api", - "core/node/logs_bloom_backfill", - "core/node/da_clients", - # Libraries - "core/lib/db_connection", - "core/lib/zksync_core_leftovers", - "core/lib/basic_types", - "core/lib/config", - "core/lib/constants", - "core/lib/contract_verifier", - "core/lib/contracts", - "core/lib/circuit_breaker", - "core/lib/dal", - "core/lib/env_config", - "core/lib/da_client", - "core/lib/eth_client", - "core/lib/eth_signer", - "core/lib/l1_contract_interface", - "core/lib/mempool", - "core/lib/merkle_tree", - "core/lib/mini_merkle_tree", - "core/lib/node_framework_derive", - "core/lib/object_store", - "core/lib/prover_interface", - "core/lib/queued_job_processor", - "core/lib/state", - "core/lib/storage", - "core/lib/tee_verifier", - "core/lib/types", - "core/lib/protobuf_config", - "core/lib/utils", - "core/lib/vlog", - "core/lib/multivm", - "core/lib/vm_interface", - "core/lib/vm_executor", - "core/lib/web3_decl", - "core/lib/snapshots_applier", - "core/lib/crypto_primitives", - "core/lib/external_price_api", - "core/lib/test_contracts", - # Test infrastructure - "core/tests/loadnext", - "core/tests/vm-benchmark", -] -resolver = "2" - -exclude = [] - -# for `perf` profiling -[profile.perf] -inherits = "release" -debug = true - -[workspace.package] -version = "0.1.0" -edition = "2021" -authors = ["The Matter Labs Team "] -homepage = "https://zksync.io/" -repository = "https://github.com/matter-labs/zksync-era" -license = "MIT OR Apache-2.0" -keywords = ["blockchain", "zksync"] -categories = ["cryptography"] - -[workspace.dependencies] -# "External" dependencies -anyhow = "1" -assert_matches = "1.5" -async-trait = "0.1" -async-recursion = "1" -axum = "0.7.5" -backon = "0.4.4" -bigdecimal = "0.4.5" -bincode = "1" -blake2 = "0.10" -bytes = "1" -chrono = "0.4" -clap = "4.2.2" -codegen = "0.2.0" -const-decoder = "0.4.0" -criterion = "0.4.0" -ctrlc = "3.1" -dashmap = "5.5.3" -derive_more = "1.0.0" -envy = "0.4" -ethabi = "18.0.0" -flate2 = "1.0.28" -fraction = "0.15.3" -futures = "0.3" -futures-util = "0.3" -glob = "0.3" -google-cloud-auth = "0.16.0" -google-cloud-storage = "0.20.0" -governor = "0.4.2" -hex = "0.4" -http = "1.1" -http-body-util = "0.1.2" -httpmock = "0.7.0" -hyper = "1.3" -insta = "1.29.0" -itertools = "0.10" -jsonrpsee = { version = "0.23", default-features = false } -leb128 = "0.2.5" -lru = { version = "0.12.1", default-features = false } -mini-moka = "0.10.0" -num = "0.4.0" -num_cpus = "1.13" -num_enum = "0.7.2" -octocrab = "0.41" -once_cell = "1" -opentelemetry = "0.24.0" -opentelemetry_sdk = "0.24.0" -opentelemetry-otlp = "0.17.0" -opentelemetry-semantic-conventions = "0.16.0" -opentelemetry-appender-tracing = "0.5" -pin-project-lite = "0.2.13" -pretty_assertions = "1" -prost = "0.12.6" -rand = "0.8" -rayon = "1.3.1" -regex = "1" -reqwest = "0.12" -rlp = "0.5" -rocksdb = "0.21" -rustc_version = "0.4.0" -rustls = "0.23" -secp256k1 = { version = "0.27.0", features = ["recovery", "global-context"] } -secrecy = "0.8.0" -semver = "1" -sentry = "0.31" -serde = "1" -serde_json = "1" -serde_with = "1" -serde_yaml = "0.9" -sha2 = "0.10.8" -sha3 = "0.10.8" -sqlx = "0.8.1" -static_assertions = "1.1" -structopt = "0.3.20" -strum = "0.26" -tempfile = "3.0.2" -test-casing = "0.1.2" -test-log = "0.2.15" -thiserror = "1" -thread_local = "1.1" -tikv-jemallocator = "0.5" -tiny-keccak = "2" -tokio = "1" -tower = "0.4.13" -tower-http = "0.5.2" -tracing = "0.1" -tracing-subscriber = "0.3" -tracing-opentelemetry = "0.25.0" -time = "0.3.36" # Has to be same as used by `tracing-subscriber` -url = "2" -web3 = "0.19.0" -yab = "0.1.0" - -# Proc-macro -syn = "2.0" -quote = "1.0" -proc-macro2 = "1.0" -trybuild = "1.0" - -# "Internal" dependencies -vise = "0.2.0" -vise-exporter = "0.2.0" -foundry-compilers = { version = "0.11.6", git = "https://github.com/Moonsong-Labs/compilers.git", rev = "7c69695e5c75451f158dd2456bf8c94a7492ea0b" } - -# DA clients' dependencies -# Avail -base58 = "0.2.0" -scale-encode = "0.5.0" -blake2b_simd = "1.0.2" -subxt-metadata = "0.34.0" -parity-scale-codec = { version = "3.6.9", default-features = false } -subxt-signer = { version = "0.34", default-features = false } - -# Celestia -celestia-types = "0.6.1" -bech32 = "0.11.0" -ripemd = "0.1.3" -tonic = { version = "0.11.0", default-features = false } -pbjson-types = "0.6.0" - -# Eigen -tokio-stream = "0.1.16" - -# Here and below: -# We *always* pin the latest version of protocol to disallow accidental changes in the execution logic. -# However, for the historical version of protocol crates, we have lax requirements. Otherwise, -# Bumping a crypto dependency like `boojum` would require us to republish all the historical packages. -circuit_encodings = "=0.150.19" -circuit_sequencer_api = "=0.150.19" -circuit_definitions = "=0.150.19" -crypto_codegen = { package = "zksync_solidity_vk_codegen",version = "=0.30.12" } -kzg = { package = "zksync_kzg", version = "=0.150.19" } -zk_evm = { version = "=0.133.0" } -zk_evm_1_3_1 = { package = "zk_evm", version = "0.131.0-rc.2" } -zk_evm_1_3_3 = { package = "zk_evm", version = "0.133" } -zk_evm_1_4_0 = { package = "zk_evm", version = "0.140" } -zk_evm_1_4_1 = { package = "zk_evm", version = "0.141" } -zk_evm_1_5_0 = { package = "zk_evm", version = "=0.150.19" } -fflonk = "=0.30.12" - -# New VM; pinned to a specific commit because of instability -zksync_vm2 = { git = "https://github.com/matter-labs/vm2.git", rev = "457d8a7eea9093af9440662e33e598c13ba41633" } - -# Consensus dependencies. -zksync_concurrency = "=0.7.0" -zksync_consensus_bft = "=0.7.0" -zksync_consensus_crypto = "=0.7.0" -zksync_consensus_executor = "=0.7.0" -zksync_consensus_network = "=0.7.0" -zksync_consensus_roles = "=0.7.0" -zksync_consensus_storage = "=0.7.0" -zksync_consensus_utils = "=0.7.0" -zksync_protobuf = "=0.7.0" -zksync_protobuf_build = "=0.7.0" - -# "Local" dependencies -zksync_multivm = { version = "0.1.0", path = "core/lib/multivm" } -zksync_vlog = { version = "0.1.0", path = "core/lib/vlog" } -zksync_vm_interface = { version = "0.1.0", path = "core/lib/vm_interface" } -zksync_vm_executor = { version = "0.1.0", path = "core/lib/vm_executor" } -zksync_basic_types = { version = "0.1.0", path = "core/lib/basic_types" } -zksync_circuit_breaker = { version = "0.1.0", path = "core/lib/circuit_breaker" } -zksync_config = { version = "0.1.0", path = "core/lib/config" } -zksync_contract_verifier_lib = { version = "0.1.0", path = "core/lib/contract_verifier" } -zksync_contracts = { version = "0.1.0", path = "core/lib/contracts" } -zksync_core_leftovers = { version = "0.1.0", path = "core/lib/zksync_core_leftovers" } -zksync_dal = { version = "0.1.0", path = "core/lib/dal" } -zksync_db_connection = { version = "0.1.0", path = "core/lib/db_connection" } -zksync_env_config = { version = "0.1.0", path = "core/lib/env_config" } -zksync_eth_client = { version = "0.1.0", path = "core/lib/eth_client" } -zksync_da_client = { version = "0.1.0", path = "core/lib/da_client" } -zksync_eth_signer = { version = "0.1.0", path = "core/lib/eth_signer" } -zksync_health_check = { version = "0.1.0", path = "core/lib/health_check" } -zksync_l1_contract_interface = { version = "0.1.0", path = "core/lib/l1_contract_interface" } -zksync_mempool = { version = "0.1.0", path = "core/lib/mempool" } -zksync_merkle_tree = { version = "0.1.0", path = "core/lib/merkle_tree" } -zksync_bin_metadata = { version = "0.1.0", path = "core/lib/bin_metadata" } -zksync_mini_merkle_tree = { version = "0.1.0", path = "core/lib/mini_merkle_tree" } -zksync_object_store = { version = "0.1.0", path = "core/lib/object_store" } -zksync_protobuf_config = { version = "0.1.0", path = "core/lib/protobuf_config" } -zksync_prover_interface = { version = "0.1.0", path = "core/lib/prover_interface" } -zksync_queued_job_processor = { version = "0.1.0", path = "core/lib/queued_job_processor" } -zksync_snapshots_applier = { version = "0.1.0", path = "core/lib/snapshots_applier" } -zksync_state = { version = "0.1.0", path = "core/lib/state" } -zksync_storage = { version = "0.1.0", path = "core/lib/storage" } -zksync_system_constants = { version = "0.1.0", path = "core/lib/constants" } -zksync_tee_verifier = { version = "0.1.0", path = "core/lib/tee_verifier" } -zksync_test_contracts = { version = "0.1.0", path = "core/lib/test_contracts" } -zksync_types = { version = "0.1.0", path = "core/lib/types" } -zksync_utils = { version = "0.1.0", path = "core/lib/utils" } -zksync_web3_decl = { version = "0.1.0", path = "core/lib/web3_decl" } -zksync_crypto_primitives = { version = "0.1.0", path = "core/lib/crypto_primitives" } -zksync_external_price_api = { version = "0.1.0", path = "core/lib/external_price_api" } - -# Framework and components -zksync_node_framework = { version = "0.1.0", path = "core/node/node_framework" } -zksync_node_framework_derive = { version = "0.1.0", path = "core/lib/node_framework_derive" } -zksync_eth_watch = { version = "0.1.0", path = "core/node/eth_watch" } -zksync_shared_metrics = { version = "0.1.0", path = "core/node/shared_metrics" } -zksync_proof_data_handler = { version = "0.1.0", path = "core/node/proof_data_handler" } -zksync_block_reverter = { version = "0.1.0", path = "core/node/block_reverter" } -zksync_commitment_generator = { version = "0.1.0", path = "core/node/commitment_generator" } -zksync_house_keeper = { version = "0.1.0", path = "core/node/house_keeper" } -zksync_node_genesis = { version = "0.1.0", path = "core/node/genesis" } -zksync_da_dispatcher = { version = "0.1.0", path = "core/node/da_dispatcher" } -zksync_da_clients = { version = "0.1.0", path = "core/node/da_clients" } -zksync_eth_sender = { version = "0.1.0", path = "core/node/eth_sender" } -zksync_node_db_pruner = { version = "0.1.0", path = "core/node/db_pruner" } -zksync_node_fee_model = { version = "0.1.0", path = "core/node/fee_model" } -zksync_vm_runner = { version = "0.1.0", path = "core/node/vm_runner" } -zksync_external_proof_integration_api = { version = "0.1.0", path = "core/node/external_proof_integration_api" } -zksync_node_test_utils = { version = "0.1.0", path = "core/node/test_utils" } -zksync_state_keeper = { version = "0.1.0", path = "core/node/state_keeper" } -zksync_reorg_detector = { version = "0.1.0", path = "core/node/reorg_detector" } -zksync_consistency_checker = { version = "0.1.0", path = "core/node/consistency_checker" } -zksync_metadata_calculator = { version = "0.1.0", path = "core/node/metadata_calculator" } -zksync_node_sync = { version = "0.1.0", path = "core/node/node_sync" } -zksync_node_storage_init = { version = "0.1.0", path = "core/node/node_storage_init" } -zksync_node_consensus = { version = "0.1.0", path = "core/node/consensus" } -zksync_contract_verification_server = { version = "0.1.0", path = "core/node/contract_verification_server" } -zksync_node_api_server = { version = "0.1.0", path = "core/node/api_server" } -zksync_base_token_adjuster = { version = "0.1.0", path = "core/node/base_token_adjuster" } -zksync_logs_bloom_backfill = { version = "0.1.0", path = "core/node/logs_bloom_backfill" } diff --git a/bin/run_loadtest_from_github_actions b/bin/run_loadtest_from_github_actions index 149988d63d8f..9222673051a4 100755 --- a/bin/run_loadtest_from_github_actions +++ b/bin/run_loadtest_from_github_actions @@ -19,4 +19,4 @@ export CONTRACT_EXECUTION_PARAMS_RECURSIVE_CALLS=${execution_params[5]} export CONTRACT_EXECUTION_PARAMS_DEPLOYS=${execution_params[6]} # Run the test -cargo run --bin loadnext +cd core && cargo run --bin loadnext diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 12d1169f84a3..42ddd01a6775 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,5 +1,79 @@ # Changelog +## [26.2.1](https://github.com/matter-labs/zksync-era/compare/core-v26.2.0...core-v26.2.1) (2025-01-28) + + +### Bug Fixes + +* add . to readme ([#3538](https://github.com/matter-labs/zksync-era/issues/3538)) ([512dd45](https://github.com/matter-labs/zksync-era/commit/512dd459307e57762dd4cc2c78ff4151634b6941)) + +## [26.2.0](https://github.com/matter-labs/zksync-era/compare/core-v26.1.0...core-v26.2.0) (2025-01-24) + + +### Features + +* Compressor optimizations ([#3476](https://github.com/matter-labs/zksync-era/issues/3476)) ([3e931be](https://github.com/matter-labs/zksync-era/commit/3e931be6bddaacbd7d029c537db03a3c191fdc21)) + + +### Bug Fixes + +* **en:** better defaults, i.e. the same as used by main node ([#3521](https://github.com/matter-labs/zksync-era/issues/3521)) ([2b5fe98](https://github.com/matter-labs/zksync-era/commit/2b5fe983acf78f73fb6e90a6a7d041e8aef1c595)) +* **en:** Fix race condition in EN storage initialization ([#3515](https://github.com/matter-labs/zksync-era/issues/3515)) ([c916797](https://github.com/matter-labs/zksync-era/commit/c916797d49d636c9e642264786d4124ebd338ec3)) +* JSON proof serialization ([#3514](https://github.com/matter-labs/zksync-era/issues/3514)) ([516e521](https://github.com/matter-labs/zksync-era/commit/516e5210ed70b25a15a68a58c8065331aab542e0)) + +## [26.1.0](https://github.com/matter-labs/zksync-era/compare/core-v26.0.0...core-v26.1.0) (2025-01-21) + + +### Features + +* update l2 erc20 bridge address in updater as well ([#3500](https://github.com/matter-labs/zksync-era/issues/3500)) ([fe3c7b2](https://github.com/matter-labs/zksync-era/commit/fe3c7b2583bc4f9277e186334e5822ddf95bdcd0)) +* **vm:** Implement call tracing for fast VM ([#2905](https://github.com/matter-labs/zksync-era/issues/2905)) ([731b824](https://github.com/matter-labs/zksync-era/commit/731b8240abd4c0cfa42f2ce89c23f8ebf67e1bf2)) + + +### Bug Fixes + +* copy special case to fast VM call tracer ([#3509](https://github.com/matter-labs/zksync-era/issues/3509)) ([995e583](https://github.com/matter-labs/zksync-era/commit/995e583aa9b4ef6e0d8697fbb040e4b991a4248d)) +* fix execute encoding for transactions ([#3501](https://github.com/matter-labs/zksync-era/issues/3501)) ([4c381a8](https://github.com/matter-labs/zksync-era/commit/4c381a84346f8ab88d3f01dc2848c7fb5f2b788d)) +* **gateway:** erc20 workaround for gateway upgrade ([#3511](https://github.com/matter-labs/zksync-era/issues/3511)) ([c140ba8](https://github.com/matter-labs/zksync-era/commit/c140ba8f57caabf9c9bdd4bd8c9743a9ccf668be)) + + +### Performance Improvements + +* optimize get_unsealed_l1_batch_inner ([#3491](https://github.com/matter-labs/zksync-era/issues/3491)) ([9b121c9](https://github.com/matter-labs/zksync-era/commit/9b121c96bbb2e53be74aa81e0ca250ce9251f8db)) + +## [26.0.0](https://github.com/matter-labs/zksync-era/compare/core-v25.4.0...core-v26.0.0) (2025-01-17) + + +### ⚠ BREAKING CHANGES + +* **contracts:** gateway integration ([#1934](https://github.com/matter-labs/zksync-era/issues/1934)) + +### Features + +* Adapt server for new EVM bytecode hash encoding ([#3396](https://github.com/matter-labs/zksync-era/issues/3396)) ([5a1e6d2](https://github.com/matter-labs/zksync-era/commit/5a1e6d2445d4d4310fc1e54ccd44dc4254e5bcbc)) +* Add logging & metrics for mempool ([#3447](https://github.com/matter-labs/zksync-era/issues/3447)) ([64d861d](https://github.com/matter-labs/zksync-era/commit/64d861d1e1d2d46339938ee3174c58cdc3f348c3)) +* **api_server:** report gas price based on open batch ([#2868](https://github.com/matter-labs/zksync-era/issues/2868)) ([f30aca0](https://github.com/matter-labs/zksync-era/commit/f30aca00962aa34c8a7acd6e4116290a2b214dcb)) +* **contracts:** gateway integration ([#1934](https://github.com/matter-labs/zksync-era/issues/1934)) ([f06cb79](https://github.com/matter-labs/zksync-era/commit/f06cb79883bf320f50089099e0abeb95eaace470)) +* da_dispatcher refactoring ([#3409](https://github.com/matter-labs/zksync-era/issues/3409)) ([591cd86](https://github.com/matter-labs/zksync-era/commit/591cd86a1a1e6e4214d3cec74b4c601356060203)) +* **en:** make documentation more chain agnostic ([#3376](https://github.com/matter-labs/zksync-era/issues/3376)) ([361243f](https://github.com/matter-labs/zksync-era/commit/361243f3f15e01cf1f3e49b73a579cb962cf0124)) +* **eth-sender:** make base fee grow at least as fast as priority fee ([#3386](https://github.com/matter-labs/zksync-era/issues/3386)) ([78af2bf](https://github.com/matter-labs/zksync-era/commit/78af2bf786bb4f7a639fef9fd169594101818b79)) +* **eth-watch:** Change protocol upgrade schema ([#3435](https://github.com/matter-labs/zksync-era/issues/3435)) ([2c778fd](https://github.com/matter-labs/zksync-era/commit/2c778fdd3fcd1e774bcb945f14a640ccf4227a2f)) +* Features for an easier upgrade ([#3422](https://github.com/matter-labs/zksync-era/issues/3422)) ([3037ee6](https://github.com/matter-labs/zksync-era/commit/3037ee6aa976744a09882b5830d6242ad8336717)) +* FFLONK support for compressor ([#3359](https://github.com/matter-labs/zksync-era/issues/3359)) ([1a297be](https://github.com/matter-labs/zksync-era/commit/1a297bedd226c56fc2ba02dc54d79129a271a1eb)) +* pubdata type changes from sync-layer-stable ([#3425](https://github.com/matter-labs/zksync-era/issues/3425)) ([f09087b](https://github.com/matter-labs/zksync-era/commit/f09087bab397778976af42c321cbba93f9706b5a)) + + +### Bug Fixes + +* **api:** Propagate fallback errors in traces ([#3469](https://github.com/matter-labs/zksync-era/issues/3469)) ([84e3e31](https://github.com/matter-labs/zksync-era/commit/84e3e312688e3aaffe81828471d276e24432d496)) +* **en:** make EN use main node's fee input ([#3489](https://github.com/matter-labs/zksync-era/issues/3489)) ([cbf2c31](https://github.com/matter-labs/zksync-era/commit/cbf2c31e353fd7a5167fcca7e2df87026050c21a)) +* eth aggregator restriction ([#3490](https://github.com/matter-labs/zksync-era/issues/3490)) ([6cc9b9e](https://github.com/matter-labs/zksync-era/commit/6cc9b9e405b03a7e30f3c92735b7452099c165d0)) + + +### Performance Improvements + +* **eth-sender:** optimize sql query ([#3437](https://github.com/matter-labs/zksync-era/issues/3437)) ([0731f60](https://github.com/matter-labs/zksync-era/commit/0731f607a72d18decd1ff74139f190c253d807ef)) + ## [25.4.0](https://github.com/matter-labs/zksync-era/compare/core-v25.3.0...core-v25.4.0) (2024-12-19) diff --git a/Cargo.lock b/core/Cargo.lock similarity index 98% rename from Cargo.lock rename to core/Cargo.lock index 4744b424cea0..e8943b2a369a 100644 --- a/Cargo.lock +++ b/core/Cargo.lock @@ -1233,7 +1233,7 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "block_reverter" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "clap 4.5.23", @@ -1289,9 +1289,9 @@ dependencies = [ [[package]] name = "boojum" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14bd053feb7173130679a2119e105b5e78af7eb6b0e752de6793e4ee63d8e899" +checksum = "d689807d79092f8f7cfcb72a2313a43da77d56314e41324810566f385875c185" dependencies = [ "arrayvec 0.7.6", "bincode", @@ -1690,9 +1690,9 @@ dependencies = [ [[package]] name = "circuit_definitions" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ebc81d5c2f6ee8de436c242f6466fb315fe25afcbc81aa1c47dfca39a55403" +checksum = "1f04f9c7c6b39255199aaba49802c5f40f95bcff24f5a456446a912d254f4bb1" dependencies = [ "circuit_encodings", "crossbeam", @@ -1704,26 +1704,26 @@ dependencies = [ [[package]] name = "circuit_encodings" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33375d2448a78c1aed9b8755f7939a6b6f19e2fa80f44f4930a5b4c2bb7cbb44" +checksum = "fc3399f1981164c3c687ea15b1eedd35a16f28069c845a24530de21f996f3fdd" dependencies = [ "derivative", "serde", - "zk_evm 0.150.19", + "zk_evm 0.150.20", "zkevm_circuits", ] [[package]] name = "circuit_sequencer_api" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2fec5c28e5a9f085279e70e13b2eebb63a95ee0bfb99d58095ac01c1c7b256" +checksum = "b5583037ec61607ac481b0c887b7fb4f860e65c92c6f3f7be74f6bab7c40c3ce" dependencies = [ "derivative", "rayon", "serde", - "zk_evm 0.150.19", + "zk_evm 0.150.20", "zksync_bellman", ] @@ -2233,7 +2233,7 @@ dependencies = [ [[package]] name = "custom_genesis_export" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "bincode", @@ -2983,9 +2983,9 @@ dependencies = [ [[package]] name = "fflonk" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63d70f1cbf9e572ccaf22ca1dfce4b93ff48b9a5e8dd70de50d87edb960d173" +checksum = "b36c5fa909ab71b7eb4b8f7fd092f72ed83b93f2615e42f245ca808d8f308917" dependencies = [ "bincode", "byteorder", @@ -3272,9 +3272,9 @@ dependencies = [ [[package]] name = "franklin-crypto" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d7b8e5864df7f3747e5e64a5b87b4a57aa2a4a20c55c9e96a3a305a8143c45" +checksum = "8309d8fc22fc389d831390473b0ee9fe94e85f19a8b9229b9aec8aa73f5bcee3" dependencies = [ "arr_macro", "bit-vec", @@ -3485,7 +3485,7 @@ dependencies = [ [[package]] name = "genesis_generator" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "clap 4.5.23", @@ -5156,7 +5156,7 @@ checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "loadnext" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -5343,7 +5343,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "merkle_tree_consistency_checker" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "clap 4.5.23", @@ -7258,9 +7258,9 @@ dependencies = [ [[package]] name = "rescue_poseidon" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c250446885c257bee70bc0f2600229ce72f03073b87fb8f5dd278dba16b11f30" +checksum = "5e631fd184b6d2f2c04f9dc75405289d99fd0d6612d8dfbb478c01bfbab648fb" dependencies = [ "addchain", "arrayvec 0.7.6", @@ -7984,7 +7984,7 @@ dependencies = [ [[package]] name = "selector_generator" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "clap 4.5.23", @@ -8644,7 +8644,7 @@ dependencies = [ [[package]] name = "snapshots_creator" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "futures 0.3.31", @@ -8665,9 +8665,9 @@ dependencies = [ [[package]] name = "snark_wrapper" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f361c2c47b71ee43f62954ce69f7730e14acb7fb3b0f2c697da02f97327c569" +checksum = "eddb498315057210abd25e2fbe2ea30ab69a07ca0c166406a3e7c056ec8fbbfd" dependencies = [ "derivative", "rand 0.4.6", @@ -9393,7 +9393,7 @@ dependencies = [ [[package]] name = "system-constants-generator" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "codegen", "once_cell", @@ -10373,7 +10373,7 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "verified_sources_fetcher" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "serde_json", @@ -10430,7 +10430,7 @@ dependencies = [ [[package]] name = "vm-benchmark" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "assert_matches", "criterion", @@ -11160,9 +11160,9 @@ dependencies = [ [[package]] name = "zk_evm" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ee848aa90ae045457795b1c0afeb388fbd9fa1e57aa0e8791b28f405e7cc2c" +checksum = "f11d0310228af78e804e5e7deccd1ad6797fce1c44c3b8016722ab78dc183c4a" dependencies = [ "anyhow", "lazy_static", @@ -11170,7 +11170,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 0.150.19", + "zk_evm_abstractions 0.150.20", ] [[package]] @@ -11201,22 +11201,22 @@ dependencies = [ [[package]] name = "zk_evm_abstractions" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f08feaa3e3d99e1e57234fe6ba2aa062609492c6499b2344121c4a699292ab7" +checksum = "d7616edbdeeeb214211e9bdc4346b6a62c6c6118c3d2b83b7db24c01f65f6e25" dependencies = [ "anyhow", "num_enum 0.6.1", "serde", "static_assertions", - "zkevm_opcode_defs 0.150.19", + "zkevm_opcode_defs 0.150.20", ] [[package]] name = "zkevm_circuits" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760cfbbce18f42bbecd2565de9bf658234cac2431cce9b0c1df08e9df645d467" +checksum = "6f36004572f5086c513715e11f38230e2538c159d4f5d90dc518833c6fc78293" dependencies = [ "arrayvec 0.7.6", "boojum", @@ -11228,7 +11228,7 @@ dependencies = [ "seq-macro", "serde", "smallvec", - "zkevm_opcode_defs 0.150.19", + "zkevm_opcode_defs 0.150.20", "zksync_cs_derive", ] @@ -11276,9 +11276,9 @@ dependencies = [ [[package]] name = "zkevm_opcode_defs" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2bd8ef52c8f9911dd034b91d29f087ab52f80a80f9d996deb881abbb953793" +checksum = "ce6b4a47c0e7f95b51d29ca336821321cec4bbba0acdd412c3a209270a0d37fe" dependencies = [ "bitflags 2.6.0", "blake2 0.10.6", @@ -11293,7 +11293,7 @@ dependencies = [ [[package]] name = "zksync_base_token_adjuster" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -11315,7 +11315,7 @@ dependencies = [ [[package]] name = "zksync_basic_types" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "bincode", @@ -11337,9 +11337,9 @@ dependencies = [ [[package]] name = "zksync_bellman" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06d424f7e3862d7a6715179bafffbe7a5dce17129f95ac4124502ab9f1edfb8" +checksum = "78fc3c598daf718b6fc791bfbb01c4634199e479ea9b2c82d06cd108b967d441" dependencies = [ "arrayvec 0.7.6", "bit-vec", @@ -11360,7 +11360,7 @@ dependencies = [ [[package]] name = "zksync_block_reverter" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -11384,7 +11384,7 @@ dependencies = [ [[package]] name = "zksync_circuit_breaker" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -11398,7 +11398,7 @@ dependencies = [ [[package]] name = "zksync_commitment_generator" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "circuit_encodings", @@ -11411,7 +11411,7 @@ dependencies = [ "tokio", "tracing", "vise", - "zk_evm 0.150.19", + "zk_evm 0.150.20", "zksync_contracts", "zksync_dal", "zksync_eth_client", @@ -11427,9 +11427,9 @@ dependencies = [ [[package]] name = "zksync_concurrency" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8312ab73d3caa55775bd531795b507fa8f76bd9dabfaeb0954fe43e8fc1323b" +checksum = "cec98400a9e8ba02bfd029eacfe7d6fb7b85b8ef00de59d6bb119d29cc9f7442" dependencies = [ "anyhow", "once_cell", @@ -11446,7 +11446,7 @@ dependencies = [ [[package]] name = "zksync_config" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "rand 0.8.5", @@ -11463,9 +11463,9 @@ dependencies = [ [[package]] name = "zksync_consensus_bft" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb6b0944322f30f88cd7fb22f7875435b394a135fc1b479719a18c42d9fb724d" +checksum = "0fa086aeb444d3d0122014fca06959e5c1be507d63596022bd28b8cdcc5cc687" dependencies = [ "anyhow", "async-trait", @@ -11485,9 +11485,9 @@ dependencies = [ [[package]] name = "zksync_consensus_crypto" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b539960de98df3c3bd27d2d9b97de862027686bbb3bdfc5aaad5b74bb929a1" +checksum = "c04840825dfbe3b9f708d245c87618d5dcf28f29d7b58922971351068a0b8231" dependencies = [ "anyhow", "blst", @@ -11506,9 +11506,9 @@ dependencies = [ [[package]] name = "zksync_consensus_executor" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a75d86368579d5aa59b1baebbdc1aebca7c9234f3e3cba734db7e9bbc4880b0" +checksum = "d6d369ec72851aecdfb24c99ecb50b7c177f0ce7068bb84a17a294a26fb92fab" dependencies = [ "anyhow", "async-trait", @@ -11528,9 +11528,9 @@ dependencies = [ [[package]] name = "zksync_consensus_network" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30f73993b7d677dfd4e4f2598dd20906e6a5f3a2168c6cab3a599c056dc5e39a" +checksum = "6a74ed5a9a48d403b48c7ed0dea8cf2cd239e407227657aac27d75d00c3e4bcc" dependencies = [ "anyhow", "async-trait", @@ -11565,9 +11565,9 @@ dependencies = [ [[package]] name = "zksync_consensus_roles" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49949546895a10431b9daec6ec4208ef0917ace006446d304b51f5b234ba462" +checksum = "05498eab1de26869028b5822cfa4490cac625508d427d59668dc73e8162de65f" dependencies = [ "anyhow", "bit-vec", @@ -11587,9 +11587,9 @@ dependencies = [ [[package]] name = "zksync_consensus_storage" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb0d6a54e7d8d2adeee4ba38662161e9309180ad497299092e5641db9fb1c1e" +checksum = "b20eb99fdd0e171a370214d2b7c99b5d4e8c11b9828a6b5705423bf653849a70" dependencies = [ "anyhow", "async-trait", @@ -11607,9 +11607,9 @@ dependencies = [ [[package]] name = "zksync_consensus_utils" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723e2a4b056cc5af192a83163c89a6951ee75c098cc5c4a4cdc435f4232d88bd" +checksum = "f2f9fa69ef68e6a1955a1d7b33077103fb6d106b560fec0d599c6de268f5be03" dependencies = [ "anyhow", "rand 0.8.5", @@ -11619,7 +11619,7 @@ dependencies = [ [[package]] name = "zksync_consistency_checker" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -11644,7 +11644,7 @@ dependencies = [ [[package]] name = "zksync_contract_verification_server" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "axum 0.7.9", @@ -11663,7 +11663,7 @@ dependencies = [ [[package]] name = "zksync_contract_verifier" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "clap 4.5.23", @@ -11680,7 +11680,7 @@ dependencies = [ [[package]] name = "zksync_contract_verifier_lib" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -11712,7 +11712,7 @@ dependencies = [ [[package]] name = "zksync_contracts" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "bincode", "envy", @@ -11726,7 +11726,7 @@ dependencies = [ [[package]] name = "zksync_core_leftovers" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "ctrlc", @@ -11740,7 +11740,7 @@ dependencies = [ [[package]] name = "zksync_crypto_primitives" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "blake2 0.10.6", @@ -11756,9 +11756,9 @@ dependencies = [ [[package]] name = "zksync_cs_derive" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23237b019a469bfa59c11108beff84a63a43f52fa3afbf1b461527031fc47644" +checksum = "97ab7469afcd9e1cb220fe17b3c9f2abe031648b94add97da37065c58be08554" dependencies = [ "proc-macro-error", "proc-macro2 1.0.92", @@ -11768,7 +11768,7 @@ dependencies = [ [[package]] name = "zksync_da_client" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -11777,7 +11777,7 @@ dependencies = [ [[package]] name = "zksync_da_clients" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -11821,7 +11821,7 @@ dependencies = [ [[package]] name = "zksync_da_dispatcher" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "chrono", @@ -11838,7 +11838,7 @@ dependencies = [ [[package]] name = "zksync_dal" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "bigdecimal", @@ -11848,6 +11848,7 @@ dependencies = [ "itertools 0.10.5", "prost 0.12.6", "rand 0.8.5", + "rayon", "serde", "serde_json", "sqlx", @@ -11874,7 +11875,7 @@ dependencies = [ [[package]] name = "zksync_db_connection" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -11892,7 +11893,7 @@ dependencies = [ [[package]] name = "zksync_env_config" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "envy", @@ -11904,7 +11905,7 @@ dependencies = [ [[package]] name = "zksync_eth_client" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "assert_matches", "async-trait", @@ -11926,7 +11927,7 @@ dependencies = [ [[package]] name = "zksync_eth_sender" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -11956,7 +11957,7 @@ dependencies = [ [[package]] name = "zksync_eth_signer" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "async-trait", "rlp", @@ -11967,7 +11968,7 @@ dependencies = [ [[package]] name = "zksync_eth_watch" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-recursion", @@ -11994,7 +11995,7 @@ dependencies = [ [[package]] name = "zksync_external_node" -version = "25.4.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12048,7 +12049,7 @@ dependencies = [ [[package]] name = "zksync_external_price_api" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -12069,7 +12070,7 @@ dependencies = [ [[package]] name = "zksync_external_proof_integration_api" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -12087,9 +12088,9 @@ dependencies = [ [[package]] name = "zksync_ff" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5aa518ed0ea7ef737d50de02025f5a593dbb11104b3c1bf5a00f39581b47dc" +checksum = "6583c2db6dc787600879d27ec98d2eb628a757ee41831e54f8be1dae4acc599f" dependencies = [ "byteorder", "hex", @@ -12100,9 +12101,9 @@ dependencies = [ [[package]] name = "zksync_ff_derive" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b43100a1278e2f64820368db8751c2441860ea74ab5749074cf8f864647af" +checksum = "8f62e93dde881d8dd44d1864c7682394dde6d18e582fc5af78768221a1766fdf" dependencies = [ "num-bigint 0.4.6", "num-integer", @@ -12115,7 +12116,7 @@ dependencies = [ [[package]] name = "zksync_health_check" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "assert_matches", "async-trait", @@ -12130,7 +12131,7 @@ dependencies = [ [[package]] name = "zksync_house_keeper" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -12145,9 +12146,9 @@ dependencies = [ [[package]] name = "zksync_kzg" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9da880b8282a97d9dfd6ac9f0189d310c0602059a8de20aa66a883979d6adba" +checksum = "174f82592590901cbcf2b298059c89f817b404299ffbd050a3915ea72357f545" dependencies = [ "boojum", "derivative", @@ -12162,7 +12163,7 @@ dependencies = [ [[package]] name = "zksync_l1_contract_interface" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "circuit_definitions", @@ -12183,7 +12184,7 @@ dependencies = [ [[package]] name = "zksync_logs_bloom_backfill" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "tokio", @@ -12195,7 +12196,7 @@ dependencies = [ [[package]] name = "zksync_mempool" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "tracing", "zksync_types", @@ -12203,7 +12204,7 @@ dependencies = [ [[package]] name = "zksync_merkle_tree" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12232,7 +12233,7 @@ dependencies = [ [[package]] name = "zksync_metadata_calculator" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12266,7 +12267,7 @@ dependencies = [ [[package]] name = "zksync_mini_merkle_tree" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "criterion", "once_cell", @@ -12276,7 +12277,7 @@ dependencies = [ [[package]] name = "zksync_multivm" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12295,7 +12296,7 @@ dependencies = [ "zk_evm 0.133.0", "zk_evm 0.140.0", "zk_evm 0.141.0", - "zk_evm 0.150.19", + "zk_evm 0.150.20", "zksync_contracts", "zksync_eth_signer", "zksync_mini_merkle_tree", @@ -12308,7 +12309,7 @@ dependencies = [ [[package]] name = "zksync_node_api_server" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12335,7 +12336,7 @@ dependencies = [ "tower-http 0.5.2", "tracing", "vise", - "zk_evm 0.150.19", + "zk_evm 0.150.20", "zksync_config", "zksync_consensus_roles", "zksync_contracts", @@ -12362,7 +12363,7 @@ dependencies = [ [[package]] name = "zksync_node_consensus" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -12406,7 +12407,7 @@ dependencies = [ [[package]] name = "zksync_node_db_pruner" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12428,7 +12429,7 @@ dependencies = [ [[package]] name = "zksync_node_fee_model" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -12447,7 +12448,7 @@ dependencies = [ [[package]] name = "zksync_node_framework" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12510,7 +12511,7 @@ dependencies = [ [[package]] name = "zksync_node_framework_derive" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "proc-macro2 1.0.92", "quote 1.0.37", @@ -12519,7 +12520,7 @@ dependencies = [ [[package]] name = "zksync_node_genesis" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "bincode", @@ -12540,7 +12541,7 @@ dependencies = [ [[package]] name = "zksync_node_storage_init" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -12562,7 +12563,7 @@ dependencies = [ [[package]] name = "zksync_node_sync" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12597,7 +12598,7 @@ dependencies = [ [[package]] name = "zksync_node_test_utils" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "zksync_contracts", "zksync_dal", @@ -12609,7 +12610,7 @@ dependencies = [ [[package]] name = "zksync_object_store" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12634,9 +12635,9 @@ dependencies = [ [[package]] name = "zksync_pairing" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f0d96f3e386f3b4c76a614d73b71714d6712e917d462bf8053b8af352da0b3" +checksum = "baafdd03ca7a48dc9b6808be3630f2d8a003aa425d71946e9158d8c0aeb1cc79" dependencies = [ "byteorder", "cfg-if", @@ -12647,7 +12648,7 @@ dependencies = [ [[package]] name = "zksync_proof_data_handler" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "axum 0.7.9", @@ -12671,9 +12672,9 @@ dependencies = [ [[package]] name = "zksync_protobuf" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8986ad796f8e00d8999fee72effba1a21bce40f5f877d681ac9cd89a94834d8" +checksum = "d9032e12528c2466293b206d6edb53b7e900e4a4cc4573e4d075ac2dc00e1b55" dependencies = [ "anyhow", "bit-vec", @@ -12692,9 +12693,9 @@ dependencies = [ [[package]] name = "zksync_protobuf_build" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d870b31995e3acb8e47afeb68ebeeffcf6121e70020e65b3d5d31692115d236" +checksum = "7c644fc8ef3c4d343ea42cebd5551e3562933f15dd9b0e68a52c2657603eb0f5" dependencies = [ "anyhow", "heck 0.5.0", @@ -12709,7 +12710,7 @@ dependencies = [ [[package]] name = "zksync_protobuf_config" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "hex", @@ -12729,7 +12730,7 @@ dependencies = [ [[package]] name = "zksync_prover_interface" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "bincode", "chrono", @@ -12741,6 +12742,7 @@ dependencies = [ "serde_with", "strum", "tokio", + "zksync_bellman", "zksync_object_store", "zksync_types", "zksync_vm_interface", @@ -12748,7 +12750,7 @@ dependencies = [ [[package]] name = "zksync_queued_job_processor" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -12760,7 +12762,7 @@ dependencies = [ [[package]] name = "zksync_reorg_detector" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12781,7 +12783,7 @@ dependencies = [ [[package]] name = "zksync_server" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "clap 4.5.23", @@ -12811,7 +12813,7 @@ dependencies = [ [[package]] name = "zksync_shared_metrics" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "rustc_version 0.4.1", "serde", @@ -12823,7 +12825,7 @@ dependencies = [ [[package]] name = "zksync_snapshots_applier" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12845,9 +12847,9 @@ dependencies = [ [[package]] name = "zksync_solidity_vk_codegen" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb10f377dcc24fe2268cc5f530c16af1c879a791570d8fe64064b58ba143c7cc" +checksum = "bb05a12f5552d7947427f755e29f548ce94733851f1fa16edaf8b75c28033e73" dependencies = [ "ethereum-types", "franklin-crypto", @@ -12862,7 +12864,7 @@ dependencies = [ [[package]] name = "zksync_state" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12887,7 +12889,7 @@ dependencies = [ [[package]] name = "zksync_state_keeper" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -12927,7 +12929,7 @@ dependencies = [ [[package]] name = "zksync_storage" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "num_cpus", "once_cell", @@ -12940,7 +12942,7 @@ dependencies = [ [[package]] name = "zksync_system_constants" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "once_cell", "zksync_basic_types", @@ -12948,7 +12950,7 @@ dependencies = [ [[package]] name = "zksync_tee_prover" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -12973,7 +12975,7 @@ dependencies = [ [[package]] name = "zksync_tee_verifier" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "bincode", @@ -12991,7 +12993,7 @@ dependencies = [ [[package]] name = "zksync_test_contracts" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "ethabi", "foundry-compilers", @@ -13007,7 +13009,7 @@ dependencies = [ [[package]] name = "zksync_types" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -13016,6 +13018,7 @@ dependencies = [ "bincode", "blake2 0.10.6", "chrono", + "ciborium", "derive_more 1.0.0", "hex", "itertools 0.10.5", @@ -13042,7 +13045,7 @@ dependencies = [ [[package]] name = "zksync_utils" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -13058,7 +13061,7 @@ dependencies = [ [[package]] name = "zksync_vlog" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "chrono", @@ -13088,8 +13091,8 @@ source = "git+https://github.com/matter-labs/vm2.git?rev=457d8a7eea9093af9440662 dependencies = [ "enum_dispatch", "primitive-types", - "zk_evm_abstractions 0.150.19", - "zkevm_opcode_defs 0.150.19", + "zk_evm_abstractions 0.150.20", + "zkevm_opcode_defs 0.150.20", "zksync_vm2_interface", ] @@ -13103,7 +13106,7 @@ dependencies = [ [[package]] name = "zksync_vm_executor" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -13121,7 +13124,7 @@ dependencies = [ [[package]] name = "zksync_vm_interface" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -13139,7 +13142,7 @@ dependencies = [ [[package]] name = "zksync_vm_runner" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", @@ -13173,7 +13176,7 @@ dependencies = [ [[package]] name = "zksync_web3_decl" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "assert_matches", diff --git a/core/Cargo.toml b/core/Cargo.toml new file mode 100644 index 000000000000..e636e1079f13 --- /dev/null +++ b/core/Cargo.toml @@ -0,0 +1,328 @@ +[workspace] +members = [ + # Binaries + "bin/block_reverter", + "bin/contract-verifier", + "bin/custom_genesis_export", + "bin/external_node", + "bin/merkle_tree_consistency_checker", + "bin/snapshots_creator", + "bin/selector_generator", + "bin/system-constants-generator", + "bin/verified_sources_fetcher", + "bin/zksync_server", + "bin/genesis_generator", + "bin/zksync_tee_prover", + # Node services + "node/node_framework", + "node/proof_data_handler", + "node/block_reverter", + "node/commitment_generator", + "node/house_keeper", + "node/genesis", + "node/shared_metrics", + "node/db_pruner", + "node/fee_model", + "node/da_dispatcher", + "node/eth_sender", + "node/vm_runner", + "node/test_utils", + "node/state_keeper", + "node/reorg_detector", + "node/consistency_checker", + "node/metadata_calculator", + "node/node_sync", + "node/node_storage_init", + "node/consensus", + "node/contract_verification_server", + "node/api_server", + "node/base_token_adjuster", + "node/external_proof_integration_api", + "node/logs_bloom_backfill", + "node/da_clients", + # Libraries + "lib/db_connection", + "lib/zksync_core_leftovers", + "lib/basic_types", + "lib/config", + "lib/constants", + "lib/contract_verifier", + "lib/contracts", + "lib/circuit_breaker", + "lib/dal", + "lib/env_config", + "lib/da_client", + "lib/eth_client", + "lib/eth_signer", + "lib/l1_contract_interface", + "lib/mempool", + "lib/merkle_tree", + "lib/mini_merkle_tree", + "lib/node_framework_derive", + "lib/object_store", + "lib/prover_interface", + "lib/queued_job_processor", + "lib/state", + "lib/storage", + "lib/tee_verifier", + "lib/types", + "lib/protobuf_config", + "lib/utils", + "lib/vlog", + "lib/multivm", + "lib/vm_interface", + "lib/vm_executor", + "lib/web3_decl", + "lib/snapshots_applier", + "lib/crypto_primitives", + "lib/external_price_api", + "lib/test_contracts", + # Test infrastructure + "tests/loadnext", + "tests/vm-benchmark", +] +resolver = "2" + +exclude = [] + +# for `perf` profiling +[profile.perf] +inherits = "release" +debug = true + +[workspace.package] +version = "26.2.1-non-semver-compat" +edition = "2021" +authors = ["The Matter Labs Team "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/zksync-era" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] + +[workspace.dependencies] +# "External" dependencies +anyhow = "1" +assert_matches = "1.5" +async-trait = "0.1" +async-recursion = "1" +axum = "0.7.5" +backon = "0.4.4" +bigdecimal = "0.4.5" +bincode = "1" +blake2 = "0.10" +bytes = "1" +chrono = "0.4" +clap = "4.2.2" +codegen = "0.2.0" +const-decoder = "0.4.0" +criterion = "0.4.0" +ctrlc = "3.1" +dashmap = "5.5.3" +derive_more = "1.0.0" +envy = "0.4" +ethabi = "18.0.0" +flate2 = "1.0.28" +fraction = "0.15.3" +futures = "0.3" +futures-util = "0.3" +glob = "0.3" +google-cloud-auth = "0.16.0" +google-cloud-storage = "0.20.0" +governor = "0.4.2" +hex = "0.4" +http = "1.1" +http-body-util = "0.1.2" +httpmock = "0.7.0" +hyper = "1.3" +insta = "1.29.0" +itertools = "0.10" +jsonrpsee = { version = "0.23", default-features = false } +leb128 = "0.2.5" +lru = { version = "0.12.1", default-features = false } +mini-moka = "0.10.0" +num = "0.4.0" +num_cpus = "1.13" +num_enum = "0.7.2" +octocrab = "0.41" +once_cell = "1" +opentelemetry = "0.24.0" +opentelemetry_sdk = "0.24.0" +opentelemetry-otlp = "0.17.0" +opentelemetry-semantic-conventions = "0.16.0" +opentelemetry-appender-tracing = "0.5" +pin-project-lite = "0.2.13" +pretty_assertions = "1" +prost = "0.12.6" +rand = "0.8" +rayon = "1.3.1" +regex = "1" +reqwest = "0.12" +rlp = "0.5" +rocksdb = "0.21" +rustc_version = "0.4.0" +rustls = "0.23" +secp256k1 = { version = "0.27.0", features = ["recovery", "global-context"] } +secrecy = "0.8.0" +semver = "1" +sentry = "0.31" +serde = "1" +serde_json = "1" +serde_with = "1" +serde_yaml = "0.9" +ciborium = "0.2" +sha2 = "0.10.8" +sha3 = "0.10.8" +sqlx = "0.8.1" +static_assertions = "1.1" +structopt = "0.3.20" +strum = "0.26" +tempfile = "3.0.2" +test-casing = "0.1.2" +test-log = "0.2.15" +thiserror = "1" +thread_local = "1.1" +tikv-jemallocator = "0.5" +tiny-keccak = "2" +tokio = "1" +tower = "0.4.13" +tower-http = "0.5.2" +tracing = "0.1" +tracing-subscriber = "0.3" +tracing-opentelemetry = "0.25.0" +time = "0.3.36" # Has to be same as used by `tracing-subscriber` +url = "2" +web3 = "0.19.0" +yab = "0.1.0" + +# Proc-macro +syn = "2.0" +quote = "1.0" +proc-macro2 = "1.0" +trybuild = "1.0" + +# "Internal" dependencies +vise = "0.2.0" +vise-exporter = "0.2.0" +foundry-compilers = { version = "0.11.6", git = "https://github.com/Moonsong-Labs/compilers.git", rev = "7c69695e5c75451f158dd2456bf8c94a7492ea0b" } + +# DA clients' dependencies +# Avail +base58 = "0.2.0" +scale-encode = "0.5.0" +blake2b_simd = "1.0.2" +subxt-metadata = "0.34.0" +parity-scale-codec = { version = "3.6.9", default-features = false } +subxt-signer = { version = "0.34", default-features = false } + +# Celestia +celestia-types = "0.6.1" +bech32 = "0.11.0" +ripemd = "0.1.3" +tonic = { version = "0.11.0", default-features = false } +pbjson-types = "0.6.0" + +# Eigen +tokio-stream = "0.1.16" + +# Here and below: +# We *always* pin the latest version of protocol to disallow accidental changes in the execution logic. +# However, for the historical version of protocol crates, we have lax requirements. Otherwise, +# Bumping a crypto dependency like `boojum` would require us to republish all the historical packages. +circuit_encodings = "=0.150.20" +circuit_sequencer_api = "=0.150.20" +circuit_definitions = "=0.150.20" +crypto_codegen = { package = "zksync_solidity_vk_codegen", version = "=0.30.13" } +kzg = { package = "zksync_kzg", version = "=0.150.20" } +zk_evm = { version = "=0.133.0" } +zk_evm_1_3_1 = { package = "zk_evm", version = "0.131.0-rc.2" } +zk_evm_1_3_3 = { package = "zk_evm", version = "0.133" } +zk_evm_1_4_0 = { package = "zk_evm", version = "0.140" } +zk_evm_1_4_1 = { package = "zk_evm", version = "0.141" } +zk_evm_1_5_0 = { package = "zk_evm", version = "=0.150.20" } +fflonk = "=0.30.13" +bellman = { package = "zksync_bellman", version = "=0.30.13" } + +# New VM; pinned to a specific commit because of instability +zksync_vm2 = { git = "https://github.com/matter-labs/vm2.git", rev = "457d8a7eea9093af9440662e33e598c13ba41633" } + +# Consensus dependencies. +zksync_concurrency = "=0.8.0" +zksync_consensus_bft = "=0.8.0" +zksync_consensus_crypto = "=0.8.0" +zksync_consensus_executor = "=0.8.0" +zksync_consensus_network = "=0.8.0" +zksync_consensus_roles = "=0.8.0" +zksync_consensus_storage = "=0.8.0" +zksync_consensus_utils = "=0.8.0" +zksync_protobuf = "=0.8.0" +zksync_protobuf_build = "=0.8.0" + +# "Local" dependencies +zksync_multivm = { version = "26.2.1-non-semver-compat", path = "lib/multivm" } +zksync_vlog = { version = "26.2.1-non-semver-compat", path = "lib/vlog" } +zksync_vm_interface = { version = "26.2.1-non-semver-compat", path = "lib/vm_interface" } +zksync_vm_executor = { version = "26.2.1-non-semver-compat", path = "lib/vm_executor" } +zksync_basic_types = { version = "26.2.1-non-semver-compat", path = "lib/basic_types" } +zksync_circuit_breaker = { version = "26.2.1-non-semver-compat", path = "lib/circuit_breaker" } +zksync_config = { version = "26.2.1-non-semver-compat", path = "lib/config" } +zksync_contract_verifier_lib = { version = "26.2.1-non-semver-compat", path = "lib/contract_verifier" } +zksync_contracts = { version = "26.2.1-non-semver-compat", path = "lib/contracts" } +zksync_core_leftovers = { version = "26.2.1-non-semver-compat", path = "lib/zksync_core_leftovers" } +zksync_dal = { version = "26.2.1-non-semver-compat", path = "lib/dal" } +zksync_db_connection = { version = "26.2.1-non-semver-compat", path = "lib/db_connection" } +zksync_env_config = { version = "26.2.1-non-semver-compat", path = "lib/env_config" } +zksync_eth_client = { version = "26.2.1-non-semver-compat", path = "lib/eth_client" } +zksync_da_client = { version = "26.2.1-non-semver-compat", path = "lib/da_client" } +zksync_eth_signer = { version = "26.2.1-non-semver-compat", path = "lib/eth_signer" } +zksync_health_check = { version = "26.2.1-non-semver-compat", path = "lib/health_check" } +zksync_l1_contract_interface = { version = "26.2.1-non-semver-compat", path = "lib/l1_contract_interface" } +zksync_mempool = { version = "26.2.1-non-semver-compat", path = "lib/mempool" } +zksync_merkle_tree = { version = "26.2.1-non-semver-compat", path = "lib/merkle_tree" } +zksync_bin_metadata = { version = "=26.1.0-non-semver-compat", path = "lib/bin_metadata" } +zksync_mini_merkle_tree = { version = "26.2.1-non-semver-compat", path = "lib/mini_merkle_tree" } +zksync_object_store = { version = "26.2.1-non-semver-compat", path = "lib/object_store" } +zksync_protobuf_config = { version = "26.2.1-non-semver-compat", path = "lib/protobuf_config" } +zksync_prover_interface = { version = "26.2.1-non-semver-compat", path = "lib/prover_interface" } +zksync_queued_job_processor = { version = "26.2.1-non-semver-compat", path = "lib/queued_job_processor" } +zksync_snapshots_applier = { version = "26.2.1-non-semver-compat", path = "lib/snapshots_applier" } +zksync_state = { version = "26.2.1-non-semver-compat", path = "lib/state" } +zksync_storage = { version = "26.2.1-non-semver-compat", path = "lib/storage" } +zksync_system_constants = { version = "26.2.1-non-semver-compat", path = "lib/constants" } +zksync_tee_verifier = { version = "26.2.1-non-semver-compat", path = "lib/tee_verifier" } +zksync_test_contracts = { version = "26.2.1-non-semver-compat", path = "lib/test_contracts" } +zksync_types = { version = "26.2.1-non-semver-compat", path = "lib/types" } +zksync_utils = { version = "26.2.1-non-semver-compat", path = "lib/utils" } +zksync_web3_decl = { version = "26.2.1-non-semver-compat", path = "lib/web3_decl" } +zksync_crypto_primitives = { version = "26.2.1-non-semver-compat", path = "lib/crypto_primitives" } +zksync_external_price_api = { version = "26.2.1-non-semver-compat", path = "lib/external_price_api" } + +# Framework and components +zksync_node_framework = { version = "26.2.1-non-semver-compat", path = "node/node_framework" } +zksync_node_framework_derive = { version = "26.2.1-non-semver-compat", path = "lib/node_framework_derive" } +zksync_eth_watch = { version = "26.2.1-non-semver-compat", path = "node/eth_watch" } +zksync_shared_metrics = { version = "26.2.1-non-semver-compat", path = "node/shared_metrics" } +zksync_proof_data_handler = { version = "26.2.1-non-semver-compat", path = "node/proof_data_handler" } +zksync_block_reverter = { version = "26.2.1-non-semver-compat", path = "node/block_reverter" } +zksync_commitment_generator = { version = "26.2.1-non-semver-compat", path = "node/commitment_generator" } +zksync_house_keeper = { version = "26.2.1-non-semver-compat", path = "node/house_keeper" } +zksync_node_genesis = { version = "26.2.1-non-semver-compat", path = "node/genesis" } +zksync_da_dispatcher = { version = "26.2.1-non-semver-compat", path = "node/da_dispatcher" } +zksync_da_clients = { version = "26.2.1-non-semver-compat", path = "node/da_clients" } +zksync_eth_sender = { version = "26.2.1-non-semver-compat", path = "node/eth_sender" } +zksync_node_db_pruner = { version = "26.2.1-non-semver-compat", path = "node/db_pruner" } +zksync_node_fee_model = { version = "26.2.1-non-semver-compat", path = "node/fee_model" } +zksync_vm_runner = { version = "26.2.1-non-semver-compat", path = "node/vm_runner" } +zksync_external_proof_integration_api = { version = "26.2.1-non-semver-compat", path = "node/external_proof_integration_api" } +zksync_node_test_utils = { version = "26.2.1-non-semver-compat", path = "node/test_utils" } +zksync_state_keeper = { version = "26.2.1-non-semver-compat", path = "node/state_keeper" } +zksync_reorg_detector = { version = "26.2.1-non-semver-compat", path = "node/reorg_detector" } +zksync_consistency_checker = { version = "26.2.1-non-semver-compat", path = "node/consistency_checker" } +zksync_metadata_calculator = { version = "26.2.1-non-semver-compat", path = "node/metadata_calculator" } +zksync_node_sync = { version = "26.2.1-non-semver-compat", path = "node/node_sync" } +zksync_node_storage_init = { version = "26.2.1-non-semver-compat", path = "node/node_storage_init" } +zksync_node_consensus = { version = "26.2.1-non-semver-compat", path = "node/consensus" } +zksync_contract_verification_server = { version = "26.2.1-non-semver-compat", path = "node/contract_verification_server" } +zksync_node_api_server = { version = "26.2.1-non-semver-compat", path = "node/api_server" } +zksync_base_token_adjuster = { version = "26.2.1-non-semver-compat", path = "node/base_token_adjuster" } +zksync_logs_bloom_backfill = { version = "26.2.1-non-semver-compat", path = "node/logs_bloom_backfill" } diff --git a/core/bin/contract-verifier/src/main.rs b/core/bin/contract-verifier/src/main.rs index ab86c147977d..93f23816c67d 100644 --- a/core/bin/contract-verifier/src/main.rs +++ b/core/bin/contract-verifier/src/main.rs @@ -6,7 +6,7 @@ use tokio::sync::watch; use zksync_config::configs::PrometheusConfig; use zksync_contract_verifier_lib::ContractVerifier; use zksync_core_leftovers::temp_config_store::{load_database_secrets, load_general_config}; -use zksync_dal::{ConnectionPool, Core}; +use zksync_dal::{ConnectionPool, Core, CoreDal}; use zksync_queued_job_processor::JobProcessor; use zksync_utils::wait_for_tasks::ManagedTasks; use zksync_vlog::prometheus::PrometheusExporterConfig; @@ -25,6 +25,32 @@ struct Opt { secrets_path: Option, } +async fn perform_storage_migration(pool: &ConnectionPool) -> anyhow::Result<()> { + const BATCH_SIZE: usize = 1000; + + // Make it possible to override just in case. + let batch_size = std::env::var("CONTRACT_VERIFIER_MIGRATION_BATCH_SIZE") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(BATCH_SIZE); + + let mut storage = pool.connection().await?; + let migration_performed = storage + .contract_verification_dal() + .is_verification_info_migration_performed() + .await?; + if !migration_performed { + tracing::info!(batch_size = %batch_size, "Running the storage migration for the contract verifier table"); + storage + .contract_verification_dal() + .perform_verification_info_migration(batch_size) + .await?; + } else { + tracing::info!("Storage migration is not needed"); + } + Ok(()) +} + #[tokio::main] async fn main() -> anyhow::Result<()> { let opt = Opt::parse(); @@ -51,6 +77,8 @@ async fn main() -> anyhow::Result<()> { .build() .await?; + perform_storage_migration(&pool).await?; + let (stop_sender, stop_receiver) = watch::channel(false); let contract_verifier = ContractVerifier::new(verifier_config.compilation_timeout(), pool) .await diff --git a/core/bin/external_node/Cargo.toml b/core/bin/external_node/Cargo.toml index 799108f30723..cb75a20c3ed7 100644 --- a/core/bin/external_node/Cargo.toml +++ b/core/bin/external_node/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zksync_external_node" description = "Non-validator ZKsync node" -version = "25.4.0" # x-release-please-version +version.workspace = true edition.workspace = true authors.workspace = true homepage.workspace = true diff --git a/core/bin/external_node/README.md b/core/bin/external_node/README.md index 335ceed7b719..658dfe157068 100644 --- a/core/bin/external_node/README.md +++ b/core/bin/external_node/README.md @@ -6,7 +6,7 @@ Note: this README is under construction. ## Local development -This section describes how to run the external node locally +This section describes how to run the external node locally. ### Configuration diff --git a/core/bin/external_node/src/config/mod.rs b/core/bin/external_node/src/config/mod.rs index 235802e1073b..9274edf9d1ab 100644 --- a/core/bin/external_node/src/config/mod.rs +++ b/core/bin/external_node/src/config/mod.rs @@ -760,7 +760,7 @@ impl OptionalENConfig { } const fn default_req_entities_limit() -> usize { - 1_024 + 10_000 } const fn default_max_tx_size_bytes() -> usize { @@ -772,15 +772,15 @@ impl OptionalENConfig { } const fn default_estimate_gas_scale_factor() -> f64 { - 1.2 + 1.3 } const fn default_estimate_gas_acceptable_overestimation() -> u32 { - 1_000 + 5_000 } const fn default_gas_price_scale_factor() -> f64 { - 1.2 + 1.5 } const fn default_max_nonce_ahead() -> u32 { diff --git a/core/bin/external_node/src/config/tests.rs b/core/bin/external_node/src/config/tests.rs index dc74d124b18e..4e23fa78a4f7 100644 --- a/core/bin/external_node/src/config/tests.rs +++ b/core/bin/external_node/src/config/tests.rs @@ -82,7 +82,9 @@ fn parsing_optional_config_from_empty_env() { Duration::from_millis(100) ); assert_eq!(config.max_nonce_ahead, 50); - assert_eq!(config.estimate_gas_scale_factor, 1.2); + assert_eq!(config.estimate_gas_scale_factor, 1.3); + assert_eq!(config.gas_price_scale_factor, 1.5); + assert_eq!(config.estimate_gas_acceptable_overestimation, 5000); assert_eq!(config.vm_concurrency_limit, 2_048); assert_eq!(config.factory_deps_cache_size(), 128 * BYTES_IN_MEGABYTE); assert_eq!(config.latest_values_cache_size(), 128 * BYTES_IN_MEGABYTE); diff --git a/core/bin/merkle_tree_consistency_checker/Cargo.toml b/core/bin/merkle_tree_consistency_checker/Cargo.toml index eb7dcd81a0dc..f915f321f139 100644 --- a/core/bin/merkle_tree_consistency_checker/Cargo.toml +++ b/core/bin/merkle_tree_consistency_checker/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "merkle_tree_consistency_checker" description = "Tool to verify consistency of ZKsync Merkle Tree" -version = "0.1.0" +version.workspace = true edition.workspace = true authors.workspace = true homepage.workspace = true diff --git a/core/bin/selector_generator/Cargo.toml b/core/bin/selector_generator/Cargo.toml index b3425c11b4ec..28b3983605b3 100644 --- a/core/bin/selector_generator/Cargo.toml +++ b/core/bin/selector_generator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "selector_generator" -version = "0.1.0" +version.workspace = true edition.workspace = true authors.workspace = true homepage.workspace = true diff --git a/core/bin/snapshots_creator/Cargo.toml b/core/bin/snapshots_creator/Cargo.toml index 5a36c646e88e..aa2dde097240 100644 --- a/core/bin/snapshots_creator/Cargo.toml +++ b/core/bin/snapshots_creator/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snapshots_creator" description = "Tool to create ZKsync state snapshots" -version = "0.1.0" +version.workspace = true edition.workspace = true authors.workspace = true homepage.workspace = true diff --git a/core/bin/system-constants-generator/Cargo.toml b/core/bin/system-constants-generator/Cargo.toml index 7177d29ca743..d3b600ba258f 100644 --- a/core/bin/system-constants-generator/Cargo.toml +++ b/core/bin/system-constants-generator/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "system-constants-generator" description = "Tool for generating JSON files with the system constants for L1/L2 contracts" -version = "0.1.0" +version.workspace = true edition.workspace = true authors.workspace = true homepage.workspace = true diff --git a/core/bin/system-constants-generator/src/main.rs b/core/bin/system-constants-generator/src/main.rs index cd795f9f5326..69152545bdfe 100644 --- a/core/bin/system-constants-generator/src/main.rs +++ b/core/bin/system-constants-generator/src/main.rs @@ -212,7 +212,7 @@ fn generate_rust_fee_constants(intrinsic_gas_constants: &IntrinsicSystemGasConst } fn save_file(path_in_repo: &str, content: String) { - let zksync_home = Workspace::locate().core(); + let zksync_home = Workspace::locate().root(); let fee_constants_path = zksync_home.join(path_in_repo); fs::write(fee_constants_path, content) diff --git a/core/bin/verified_sources_fetcher/Cargo.toml b/core/bin/verified_sources_fetcher/Cargo.toml index 5fa90590ed5f..b143cafdbaee 100644 --- a/core/bin/verified_sources_fetcher/Cargo.toml +++ b/core/bin/verified_sources_fetcher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "verified_sources_fetcher" description = "Tool to fetch verified contract sources" -version = "0.1.0" +version.workspace = true edition.workspace = true authors.workspace = true homepage.workspace = true diff --git a/core/bin/verified_sources_fetcher/src/main.rs b/core/bin/verified_sources_fetcher/src/main.rs index 981eebf4a706..5ddf65fd580d 100644 --- a/core/bin/verified_sources_fetcher/src/main.rs +++ b/core/bin/verified_sources_fetcher/src/main.rs @@ -3,7 +3,7 @@ use std::io::Write; use zksync_config::configs::DatabaseSecrets; use zksync_dal::{ConnectionPool, Core, CoreDal}; use zksync_env_config::FromEnv; -use zksync_types::contract_verification_api::SourceCodeData; +use zksync_types::contract_verification::api::SourceCodeData; #[tokio::main] async fn main() { diff --git a/core/bin/zksync_server/Cargo.toml b/core/bin/zksync_server/Cargo.toml index 4cf028be8210..e5eeeb0c79a9 100644 --- a/core/bin/zksync_server/Cargo.toml +++ b/core/bin/zksync_server/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zksync_server" description = "ZKsync validator/sequencer node" -version = "0.1.0" +version.workspace = true edition.workspace = true authors.workspace = true homepage.workspace = true diff --git a/core/bin/zksync_tee_prover/Cargo.toml b/core/bin/zksync_tee_prover/Cargo.toml index b853da348ee0..303ad30cf2ac 100644 --- a/core/bin/zksync_tee_prover/Cargo.toml +++ b/core/bin/zksync_tee_prover/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zksync_tee_prover" description = "ZKsync TEE prover" -version = "0.1.0" +version.workspace = true edition.workspace = true authors.workspace = true homepage.workspace = true diff --git a/deny.toml b/core/deny.toml similarity index 100% rename from deny.toml rename to core/deny.toml diff --git a/core/genesis_export.bin b/core/genesis_export.bin new file mode 100644 index 000000000000..a65382a51ebb Binary files /dev/null and b/core/genesis_export.bin differ diff --git a/core/lib/basic_types/src/bytecode.rs b/core/lib/basic_types/src/bytecode.rs index 12b4df69a6c6..a96c5b2b10cd 100644 --- a/core/lib/basic_types/src/bytecode.rs +++ b/core/lib/basic_types/src/bytecode.rs @@ -168,6 +168,14 @@ impl BytecodeMarker { } } +/// Removes padding from the bytecode, if necessary. +pub fn trim_bytecode(bytecode_hash: BytecodeHash, raw: &[u8]) -> anyhow::Result<&[u8]> { + match bytecode_hash.marker() { + BytecodeMarker::EraVm => Ok(raw), + BytecodeMarker::Evm => trim_padded_evm_bytecode(bytecode_hash, raw), + } +} + /// Removes padding from an EVM bytecode, returning the original EVM bytecode. pub fn trim_padded_evm_bytecode(bytecode_hash: BytecodeHash, raw: &[u8]) -> anyhow::Result<&[u8]> { if bytecode_hash.marker() != BytecodeMarker::Evm { diff --git a/core/lib/contract_verifier/src/compilers/mod.rs b/core/lib/contract_verifier/src/compilers/mod.rs index c82a6575ee4c..cbaf9d2225bc 100644 --- a/core/lib/contract_verifier/src/compilers/mod.rs +++ b/core/lib/contract_verifier/src/compilers/mod.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use anyhow::Context as _; use serde::{Deserialize, Serialize}; -use zksync_types::contract_verification_api::CompilationArtifacts; +use zksync_types::contract_verification::api::CompilationArtifacts; pub(crate) use self::{ solc::{Solc, SolcInput}, diff --git a/core/lib/contract_verifier/src/compilers/solc.rs b/core/lib/contract_verifier/src/compilers/solc.rs index 10adcad3542e..4224e2a3dbcc 100644 --- a/core/lib/contract_verifier/src/compilers/solc.rs +++ b/core/lib/contract_verifier/src/compilers/solc.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, path::PathBuf, process::Stdio}; use anyhow::Context; use tokio::io::AsyncWriteExt; use zksync_queued_job_processor::async_trait; -use zksync_types::contract_verification_api::{ +use zksync_types::contract_verification::api::{ CompilationArtifacts, SourceCodeData, VerificationIncomingRequest, }; diff --git a/core/lib/contract_verifier/src/compilers/vyper.rs b/core/lib/contract_verifier/src/compilers/vyper.rs index 59b950f9f17f..46034a62e0a3 100644 --- a/core/lib/contract_verifier/src/compilers/vyper.rs +++ b/core/lib/contract_verifier/src/compilers/vyper.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, mem, path::PathBuf, process::Stdio}; use anyhow::Context; use tokio::io::AsyncWriteExt; use zksync_queued_job_processor::async_trait; -use zksync_types::contract_verification_api::{ +use zksync_types::contract_verification::api::{ CompilationArtifacts, SourceCodeData, VerificationIncomingRequest, }; diff --git a/core/lib/contract_verifier/src/compilers/zksolc.rs b/core/lib/contract_verifier/src/compilers/zksolc.rs index ff435e96aeb6..1b20f6d5d242 100644 --- a/core/lib/contract_verifier/src/compilers/zksolc.rs +++ b/core/lib/contract_verifier/src/compilers/zksolc.rs @@ -6,7 +6,7 @@ use semver::Version; use serde::{Deserialize, Serialize}; use tokio::io::AsyncWriteExt; use zksync_queued_job_processor::async_trait; -use zksync_types::contract_verification_api::{ +use zksync_types::contract_verification::api::{ CompilationArtifacts, SourceCodeData, VerificationIncomingRequest, }; @@ -65,6 +65,7 @@ pub(crate) struct Optimizer { /// Whether the optimizer is enabled. pub enabled: bool, /// The optimization mode string. + #[serde(skip_serializing_if = "Option::is_none")] pub mode: Option, } @@ -144,12 +145,24 @@ impl ZkSolc { fn parse_single_file_yul_output( output: &str, ) -> Result { - let re = Regex::new(r"Contract `.*` bytecode: 0x([\da-f]+)").unwrap(); - let cap = re - .captures(output) - .context("Yul output doesn't match regex")?; + let cap = if output.contains("Binary:\n") { + // Format of the new output + // ======= /tmp/input.yul:Empty ======= + // Binary: + // 00000001002 <..> + let re = Regex::new(r"Binary:\n([\da-f]+)").unwrap(); + re.captures(output) + .with_context(|| format!("Yul output doesn't match regex. Output: {output}"))? + } else { + // Old compiler versions + let re_old = Regex::new(r"Contract `.*` bytecode: 0x([\da-f]+)").unwrap(); + re_old + .captures(output) + .with_context(|| format!("Yul output doesn't match regex. Output: {output}"))? + }; let bytecode_str = cap.get(1).context("no matches in Yul output")?.as_str(); let bytecode = hex::decode(bytecode_str).context("invalid Yul output bytecode")?; + Ok(CompilationArtifacts { bytecode, deployed_bytecode: None, @@ -255,6 +268,9 @@ impl Compiler for ZkSolc { .context("cannot create temporary Yul file")?; file.write_all(source_code.as_bytes()) .context("failed writing Yul file")?; + + // TODO: `zksolc` support standard JSON for `yul` since 1.5.0, so we don't have + // to parse `--bin` output. let child = command .arg(file.path().to_str().unwrap()) .arg("--optimization") diff --git a/core/lib/contract_verifier/src/compilers/zkvyper.rs b/core/lib/contract_verifier/src/compilers/zkvyper.rs index 4f7c10214f8a..4056736547f6 100644 --- a/core/lib/contract_verifier/src/compilers/zkvyper.rs +++ b/core/lib/contract_verifier/src/compilers/zkvyper.rs @@ -3,7 +3,7 @@ use std::{ffi::OsString, path, path::Path, process::Stdio}; use anyhow::Context as _; use tokio::{fs, io::AsyncWriteExt}; use zksync_queued_job_processor::async_trait; -use zksync_types::contract_verification_api::CompilationArtifacts; +use zksync_types::contract_verification::api::CompilationArtifacts; use super::VyperInput; use crate::{ diff --git a/core/lib/contract_verifier/src/lib.rs b/core/lib/contract_verifier/src/lib.rs index 43da4127b809..864c7b747d43 100644 --- a/core/lib/contract_verifier/src/lib.rs +++ b/core/lib/contract_verifier/src/lib.rs @@ -15,9 +15,12 @@ use zksync_dal::{contract_verification_dal::DeployedContractData, ConnectionPool use zksync_queued_job_processor::{async_trait, JobProcessor}; use zksync_types::{ bytecode::{trim_padded_evm_bytecode, BytecodeHash, BytecodeMarker}, - contract_verification_api::{ - self as api, CompilationArtifacts, VerificationIncomingRequest, VerificationInfo, - VerificationRequest, + contract_verification::{ + api::{ + self as api, CompilationArtifacts, VerificationIncomingRequest, VerificationInfo, + VerificationProblem, VerificationRequest, + }, + contract_identifier::{ContractIdentifier, Match}, }, Address, CONTRACT_DEPLOYER_ADDRESS, }; @@ -224,7 +227,7 @@ impl ContractVerifier { async fn verify( &self, mut request: VerificationRequest, - ) -> Result { + ) -> Result<(VerificationInfo, ContractIdentifier), ContractVerifierError> { // Bytecode should be present because it is checked when accepting request. let mut storage = self .connection_pool @@ -245,6 +248,8 @@ impl ContractVerifier { let bytecode_marker = BytecodeMarker::new(deployed_contract.bytecode_hash) .context("unknown bytecode kind")?; let artifacts = self.compile(request.req.clone(), bytecode_marker).await?; + let identifier = + ContractIdentifier::from_bytecode(bytecode_marker, artifacts.deployed_bytecode()); let constructor_args = match bytecode_marker { BytecodeMarker::EraVm => self .decode_era_vm_constructor_args(&deployed_contract, request.req.contract_address)?, @@ -265,14 +270,28 @@ impl ContractVerifier { .context("invalid stored EVM bytecode")?, }; - if artifacts.deployed_bytecode() != deployed_bytecode { - tracing::info!( - request_id = request.id, - deployed = hex::encode(deployed_bytecode), - compiled = hex::encode(artifacts.deployed_bytecode()), - "Deployed (runtime) bytecode mismatch", - ); - return Err(ContractVerifierError::BytecodeMismatch); + let mut verification_problems = Vec::new(); + + match identifier.matches(deployed_bytecode) { + Match::Full => {} + Match::Partial => { + tracing::trace!( + request_id = request.id, + deployed = hex::encode(deployed_bytecode), + compiled = hex::encode(artifacts.deployed_bytecode()), + "Partial bytecode match", + ); + verification_problems.push(VerificationProblem::IncorrectMetadata); + } + Match::None => { + tracing::trace!( + request_id = request.id, + deployed = hex::encode(deployed_bytecode), + compiled = hex::encode(artifacts.deployed_bytecode()), + "Deployed (runtime) bytecode mismatch", + ); + return Err(ContractVerifierError::BytecodeMismatch); + } } match constructor_args { @@ -284,6 +303,11 @@ impl ContractVerifier { hex::encode(&args), hex::encode(provided_constructor_args) ); + // We could, in theory, accept this contract and mark it as partially verified, + // but in during verification it is always possible to reconstruct the + // constructor arguments, so there is no reason for that. + // Mismatching constructor arguments are only needed for "similar bytecodes" + // (e.g. displayed contract as verified without a direct verification request). return Err(ContractVerifierError::IncorrectConstructorArguments); } } @@ -294,11 +318,13 @@ impl ContractVerifier { let verified_at = Utc::now(); tracing::trace!(%verified_at, "verified request"); - Ok(VerificationInfo { + let info = VerificationInfo { request, artifacts, verified_at, - }) + verification_problems, + }; + Ok((info, identifier)) } async fn compile_zksolc( @@ -544,17 +570,21 @@ impl ContractVerifier { async fn process_result( &self, request_id: usize, - verification_result: Result, + verification_result: Result<(VerificationInfo, ContractIdentifier), ContractVerifierError>, ) -> anyhow::Result<()> { let mut storage = self .connection_pool .connection_tagged("contract_verifier") .await?; match verification_result { - Ok(info) => { + Ok((info, identifier)) => { storage .contract_verification_dal() - .save_verification_info(info) + .save_verification_info( + info, + identifier.bytecode_keccak256, + identifier.bytecode_without_metadata_keccak256, + ) .await?; tracing::info!("Successfully processed request with id = {request_id}"); } diff --git a/core/lib/contract_verifier/src/resolver/env.rs b/core/lib/contract_verifier/src/resolver/env.rs index 798efde64348..75fdf4e7f472 100644 --- a/core/lib/contract_verifier/src/resolver/env.rs +++ b/core/lib/contract_verifier/src/resolver/env.rs @@ -23,7 +23,7 @@ pub(crate) struct EnvCompilerResolver { impl Default for EnvCompilerResolver { fn default() -> Self { Self { - home_dir: Workspace::locate().core(), + home_dir: Workspace::locate().root(), } } } diff --git a/core/lib/contract_verifier/src/resolver/mod.rs b/core/lib/contract_verifier/src/resolver/mod.rs index a9d2bcf9049d..b2bd659408d3 100644 --- a/core/lib/contract_verifier/src/resolver/mod.rs +++ b/core/lib/contract_verifier/src/resolver/mod.rs @@ -8,7 +8,7 @@ use std::{ use anyhow::Context as _; use tokio::fs; use zksync_queued_job_processor::async_trait; -use zksync_types::contract_verification_api::CompilationArtifacts; +use zksync_types::contract_verification::api::CompilationArtifacts; pub(crate) use self::{env::EnvCompilerResolver, github::GitHubCompilerResolver}; use crate::{ diff --git a/core/lib/contract_verifier/src/tests/mod.rs b/core/lib/contract_verifier/src/tests/mod.rs index 2ffb51ceb30a..31cec03e138e 100644 --- a/core/lib/contract_verifier/src/tests/mod.rs +++ b/core/lib/contract_verifier/src/tests/mod.rs @@ -9,7 +9,7 @@ use zksync_node_test_utils::{create_l1_batch, create_l2_block}; use zksync_types::{ address_to_h256, bytecode::{pad_evm_bytecode, BytecodeHash}, - contract_verification_api::{CompilerVersions, SourceCodeData, VerificationIncomingRequest}, + contract_verification::api::{CompilerVersions, SourceCodeData, VerificationIncomingRequest}, get_code_key, get_known_code_key, l2::L2Tx, tx::IncludedTxLocation, @@ -435,7 +435,7 @@ async fn contract_verifier_basics(contract: TestContract) { let (_stop_sender, stop_receiver) = watch::channel(false); verifier.run(stop_receiver, Some(1)).await.unwrap(); - assert_request_success(&mut storage, request_id, address, &expected_bytecode).await; + assert_request_success(&mut storage, request_id, address, &expected_bytecode, &[]).await; } async fn assert_request_success( @@ -443,6 +443,7 @@ async fn assert_request_success( request_id: usize, address: Address, expected_bytecode: &[u8], + verification_problems: &[VerificationProblem], ) -> VerificationInfo { let status = storage .contract_verification_dal() @@ -465,6 +466,11 @@ async fn assert_request_success( without_internal_types(verification_info.artifacts.abi.clone()), without_internal_types(counter_contract_abi()) ); + assert_eq!( + &verification_info.verification_problems, + verification_problems + ); + verification_info } @@ -541,7 +547,7 @@ async fn verifying_evm_bytecode(contract: TestContract) { let (_stop_sender, stop_receiver) = watch::channel(false); verifier.run(stop_receiver, Some(1)).await.unwrap(); - assert_request_success(&mut storage, request_id, address, &creation_bytecode).await; + assert_request_success(&mut storage, request_id, address, &creation_bytecode, &[]).await; } #[tokio::test] @@ -708,10 +714,12 @@ async fn creation_bytecode_mismatch() { .await .unwrap(); - let mock_resolver = MockCompilerResolver::solc(move |_| CompilationArtifacts { - bytecode: vec![4; 20], // differs from `creation_bytecode` - deployed_bytecode: Some(deployed_bytecode.clone()), - abi: counter_contract_abi(), + let mock_resolver = MockCompilerResolver::solc(move |_| { + CompilationArtifacts { + bytecode: vec![4; 20], // differs from `creation_bytecode` + deployed_bytecode: Some(deployed_bytecode.clone()), + abi: counter_contract_abi(), + } }); let verifier = ContractVerifier::with_resolver( Duration::from_secs(60), diff --git a/core/lib/contract_verifier/src/tests/real.rs b/core/lib/contract_verifier/src/tests/real.rs index ba7615528e15..d82edf7b0020 100644 --- a/core/lib/contract_verifier/src/tests/real.rs +++ b/core/lib/contract_verifier/src/tests/real.rs @@ -1,11 +1,18 @@ //! Tests using real compiler toolchains. Should be prepared by calling `zkstack contract-verifier init` //! with at least one `solc` and `zksolc` version. If there are no compilers, the tests will be ignored //! unless the `RUN_CONTRACT_VERIFICATION_TEST` env var is set to `true`, in which case the tests will fail. +//! +//! You can install the compilers to run these tests with the following command: +//! ``` +//! zkstack contract-verifier init --zksolc-version=v1.5.10 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only +//! ``` use std::{env, sync::Arc, time::Duration}; use assert_matches::assert_matches; -use zksync_types::bytecode::validate_bytecode; +use zksync_types::{ + bytecode::validate_bytecode, contract_verification::contract_identifier::DetectedMetadata, +}; use super::*; @@ -19,38 +26,72 @@ impl Toolchain { const ALL: [Self; 2] = [Self::Solidity, Self::Vyper]; } +// The tests may expect specific compiler versions (e.g. contracts won't compile with Vyper 0.4.0), +// so we hardcode versions. +const ZKSOLC_VERSION: &str = "v1.5.10"; +const ERA_VM_SOLC_VERSION: &str = "0.8.26-1.0.1"; +const SOLC_VERSION: &str = "0.8.26"; +const VYPER_VERSION: &str = "v0.3.10"; +const ZKVYPER_VERSION: &str = "v1.5.4"; + #[derive(Debug, Clone)] struct TestCompilerVersions { solc: String, + eravm_solc: String, zksolc: String, vyper: String, zkvyper: String, } impl TestCompilerVersions { - fn new(versions: SupportedCompilerVersions) -> Option { - let solc = versions - .solc - .into_iter() - .find(|ver| !ver.starts_with("zkVM"))?; - Some(Self { - solc, - zksolc: versions.zksolc.into_iter().next()?, - vyper: versions.vyper.into_iter().next()?, - zkvyper: versions.zkvyper.into_iter().next()?, + fn new(versions: SupportedCompilerVersions) -> anyhow::Result { + // Stored compilers for our fork are prefixed with `zkVM-`. + let eravm_solc = format!("zkVM-{ERA_VM_SOLC_VERSION}"); + // Stored compilers for vyper do not have `v` prefix. + let vyper = VYPER_VERSION.strip_prefix("v").unwrap().to_owned(); + anyhow::ensure!( + versions.solc.contains(SOLC_VERSION), + "Expected solc version {SOLC_VERSION} to be installed, but it is not" + ); + anyhow::ensure!( + versions.solc.contains(&eravm_solc), + "Expected era-vm solc version {ERA_VM_SOLC_VERSION} to be installed, but it is not" + ); + anyhow::ensure!( + versions.zksolc.contains(ZKSOLC_VERSION), + "Expected zksolc version {ZKSOLC_VERSION} to be installed, but it is not" + ); + anyhow::ensure!( + versions.vyper.contains(&vyper), + "Expected vyper version {VYPER_VERSION} to be installed, but it is not" + ); + anyhow::ensure!( + versions.zkvyper.contains(ZKVYPER_VERSION), + "Expected zkvyper version {ZKVYPER_VERSION} to be installed, but it is not" + ); + + Ok(Self { + solc: SOLC_VERSION.to_owned(), + eravm_solc, + zksolc: ZKSOLC_VERSION.to_owned(), + vyper, + zkvyper: ZKVYPER_VERSION.to_owned(), }) } fn zksolc(self) -> ZkCompilerVersions { ZkCompilerVersions { - base: self.solc, + base: self.eravm_solc, zk: self.zksolc, } } fn solc_for_api(self, bytecode_kind: BytecodeMarker) -> CompilerVersions { CompilerVersions::Solc { - compiler_solc_version: self.solc, + compiler_solc_version: match bytecode_kind { + BytecodeMarker::Evm => self.solc, + BytecodeMarker::EraVm => self.eravm_solc, + }, compiler_zksolc_version: match bytecode_kind { BytecodeMarker::Evm => None, BytecodeMarker::EraVm => Some(self.zksolc), @@ -76,32 +117,39 @@ impl TestCompilerVersions { } } -async fn checked_env_resolver() -> Option<(EnvCompilerResolver, TestCompilerVersions)> { +async fn checked_env_resolver() -> anyhow::Result<(EnvCompilerResolver, TestCompilerVersions)> { let compiler_resolver = EnvCompilerResolver::default(); - let supported_compilers = compiler_resolver.supported_versions().await.ok()?; - Some(( + let supported_compilers = compiler_resolver.supported_versions().await?; + Ok(( compiler_resolver, TestCompilerVersions::new(supported_compilers)?, )) } -fn assert_no_compilers_expected() { +fn assert_no_compilers_expected(err: anyhow::Error) { + let error_message = format!( + "Expected pre-installed compilers since `RUN_CONTRACT_VERIFICATION_TEST=true`, but at least one compiler is not installed.\n \ + Detail: {}\n\n \ + Use the following command to install compilers:\n \ + zkstack contract-verifier init --zksolc-version={} --zkvyper-version={} --solc-version={} --vyper-version={} --era-vm-solc-version={} --only", + err, ZKSOLC_VERSION, ZKVYPER_VERSION, SOLC_VERSION, VYPER_VERSION, ERA_VM_SOLC_VERSION + ); + assert_ne!( env::var("RUN_CONTRACT_VERIFICATION_TEST").ok().as_deref(), Some("true"), - "Expected pre-installed compilers since `RUN_CONTRACT_VERIFICATION_TEST=true`, but they are not installed. \ - Use `zkstack contract-verifier init` to install compilers" + "{error_message}" ); - println!("No compilers found, skipping the test"); + println!("At least one compiler is not found, skipping the test"); } /// Simplifies initializing real compiler resolver in tests. macro_rules! real_resolver { () => { match checked_env_resolver().await { - Some(resolver_and_versions) => resolver_and_versions, - None => { - assert_no_compilers_expected(); + Ok(resolver_and_versions) => resolver_and_versions, + Err(err) => { + assert_no_compilers_expected(err); return; } } @@ -254,10 +302,16 @@ async fn compiling_yul_with_zksolc() { let req = test_yul_request(supported_compilers.solc_for_api(BytecodeMarker::EraVm)); let input = ZkSolc::build_input(req).unwrap(); let output = compiler.compile(input).await.unwrap(); + let identifier = + ContractIdentifier::from_bytecode(BytecodeMarker::EraVm, output.deployed_bytecode()); assert!(!output.bytecode.is_empty()); assert!(output.deployed_bytecode.is_none()); assert_eq!(output.abi, serde_json::json!([])); + assert_matches!( + identifier.detected_metadata, + Some(DetectedMetadata::Keccak256) + ); } #[tokio::test] @@ -272,10 +326,17 @@ async fn compiling_standalone_yul() { }); let input = Solc::build_input(req).unwrap(); let output = compiler.compile(input).await.unwrap(); + let identifier = + ContractIdentifier::from_bytecode(BytecodeMarker::Evm, output.deployed_bytecode()); assert!(!output.bytecode.is_empty()); assert_ne!(output.deployed_bytecode.unwrap(), output.bytecode); assert_eq!(output.abi, serde_json::json!([])); + assert_matches!( + identifier.detected_metadata, + None, + "No metadata for compiler yul for EVM" + ); } fn test_vyper_request( @@ -322,9 +383,15 @@ async fn using_real_zkvyper(specify_contract_file: bool) { ); let input = VyperInput::new(req).unwrap(); let output = compiler.compile(input).await.unwrap(); + let identifier = + ContractIdentifier::from_bytecode(BytecodeMarker::EraVm, output.deployed_bytecode()); validate_bytecode(&output.bytecode).unwrap(); assert_eq!(output.abi, without_internal_types(counter_contract_abi())); + assert_matches!( + identifier.detected_metadata, + Some(DetectedMetadata::Keccak256) + ); } #[test_casing(2, [false, true])] @@ -347,9 +414,13 @@ async fn using_standalone_vyper(specify_contract_file: bool) { ); let input = VyperInput::new(req).unwrap(); let output = compiler.compile(input).await.unwrap(); + let identifier = + ContractIdentifier::from_bytecode(BytecodeMarker::Evm, output.deployed_bytecode()); assert!(output.deployed_bytecode.is_some()); assert_eq!(output.abi, without_internal_types(counter_contract_abi())); + // Vyper does not provide metadata for bytecode. + assert_matches!(identifier.detected_metadata, None); } #[tokio::test] @@ -367,9 +438,13 @@ async fn using_standalone_vyper_without_optimization() { req.optimization_used = false; let input = VyperInput::new(req).unwrap(); let output = compiler.compile(input).await.unwrap(); + let identifier = + ContractIdentifier::from_bytecode(BytecodeMarker::Evm, output.deployed_bytecode()); assert!(output.deployed_bytecode.is_some()); assert_eq!(output.abi, without_internal_types(counter_contract_abi())); + // Vyper does not provide metadata for bytecode. + assert_matches!(identifier.detected_metadata, None); } #[tokio::test] @@ -469,6 +544,30 @@ async fn using_real_compiler_in_verifier(bytecode_kind: BytecodeMarker, toolchai compiler.compile(input).await.unwrap() } }; + let identifier = ContractIdentifier::from_bytecode(bytecode_kind, output.deployed_bytecode()); + + match (bytecode_kind, toolchain) { + (BytecodeMarker::Evm, Toolchain::Vyper) => { + assert!( + identifier.detected_metadata.is_none(), + "No metadata for EVM Vyper" + ); + } + (BytecodeMarker::Evm, Toolchain::Solidity) => { + assert_matches!( + identifier.detected_metadata, + Some(DetectedMetadata::Cbor), + "Cbor metadata for EVM Solidity by default" + ); + } + (BytecodeMarker::EraVm, _) => { + assert_matches!( + identifier.detected_metadata, + Some(DetectedMetadata::Keccak256), + "Keccak256 metadata for EraVM by default" + ); + } + } let pool = ConnectionPool::test_pool().await; let mut storage = pool.connection().await.unwrap(); @@ -505,7 +604,165 @@ async fn using_real_compiler_in_verifier(bytecode_kind: BytecodeMarker, toolchai let (_stop_sender, stop_receiver) = watch::channel(false); verifier.run(stop_receiver, Some(1)).await.unwrap(); - assert_request_success(&mut storage, request_id, address, &output.bytecode).await; + assert_request_success(&mut storage, request_id, address, &output.bytecode, &[]).await; +} + +#[test_casing(2, [false, true])] +#[tokio::test] +async fn using_zksolc_partial_match(use_cbor: bool) { + let (compiler_resolver, supported_compilers) = real_resolver!(); + + let mut req: VerificationIncomingRequest = VerificationIncomingRequest { + compiler_versions: supported_compilers + .clone() + .solc_for_api(BytecodeMarker::EraVm), + ..test_request(Address::repeat_byte(1), COUNTER_CONTRACT) + }; + let hash_type = if use_cbor { "ipfs" } else { "keccak256" }; + // We need to manually construct the input, since `SolSingleFile` doesn't let us specify metadata hash type. + // Note: prior to 1.5.7 field was named `bytecodeHash`. + req.source_code_data = SourceCodeData::StandardJsonInput( + serde_json::json!({ + "language": "Solidity", + "sources": { + "Counter.sol": { + "content": COUNTER_CONTRACT, + }, + }, + "settings": { + "outputSelection": { + "*": { + "": [ "abi" ], + "*": [ "abi" ] + } + }, + "isSystem": false, + "forceEvmla": false, + "metadata": { + "hashType": hash_type + }, + "optimizer": { + "enabled": true + } + } + }) + .as_object() + .unwrap() + .clone(), + ); + let contract_name = req.contract_name.clone(); + let address = Address::repeat_byte(1); + let compiler = compiler_resolver + .resolve_zksolc(&supported_compilers.clone().zksolc()) + .await + .unwrap(); + let input_for_request = ZkSolc::build_input(req.clone()).unwrap(); + + let output_for_request = compiler.compile(input_for_request).await.unwrap(); + let identifier_for_request = ContractIdentifier::from_bytecode( + BytecodeMarker::EraVm, + output_for_request.deployed_bytecode(), + ); + + // Now prepare data for contract verification storage (with different metadata). + let compiler = compiler_resolver + .resolve_zksolc(&supported_compilers.zksolc()) + .await + .unwrap(); + let mut input_for_storage = ZkSolc::build_input(req.clone()).unwrap(); + // Change the source file name. + if let ZkSolcInput::StandardJson { + input, file_name, .. + } = &mut input_for_storage + { + let source = input + .sources + .remove(&format!("{contract_name}.sol")) + .unwrap(); + let new_file_name = "random_name.sol".to_owned(); + input.sources.insert(new_file_name.clone(), source); + *file_name = new_file_name; + if use_cbor { + input.settings.other.as_object_mut().unwrap().insert( + "metadata".to_string(), + serde_json::json!({ "hashType": "ipfs"}), + ); + } + } else { + panic!("unexpected input: {input_for_storage:?}"); + } + + let output_for_storage = compiler.compile(input_for_storage).await.unwrap(); + let identifier_for_storage = ContractIdentifier::from_bytecode( + BytecodeMarker::EraVm, + output_for_storage.deployed_bytecode(), + ); + + assert_eq!( + identifier_for_request.matches(output_for_storage.deployed_bytecode()), + Match::Partial, + "must be a partial match (1)" + ); + assert_eq!( + identifier_for_storage.matches(output_for_request.deployed_bytecode()), + Match::Partial, + "must be a partial match (2)" + ); + if use_cbor { + assert_matches!( + identifier_for_request.detected_metadata, + Some(DetectedMetadata::Cbor) + ); + assert_matches!( + identifier_for_storage.detected_metadata, + Some(DetectedMetadata::Cbor) + ); + } else { + assert_matches!( + identifier_for_request.detected_metadata, + Some(DetectedMetadata::Keccak256) + ); + assert_matches!( + identifier_for_storage.detected_metadata, + Some(DetectedMetadata::Keccak256) + ); + } + + let pool = ConnectionPool::test_pool().await; + let mut storage = pool.connection().await.unwrap(); + prepare_storage(&mut storage).await; + mock_deployment( + &mut storage, + address, + output_for_storage.bytecode.clone(), + &[], + ) + .await; + let request_id = storage + .contract_verification_dal() + .add_contract_verification_request(&req) + .await + .unwrap(); + + let verifier = ContractVerifier::with_resolver( + Duration::from_secs(60), + pool.clone(), + Arc::new(compiler_resolver), + ) + .await + .unwrap(); + + let (_stop_sender, stop_receiver) = watch::channel(false); + verifier.run(stop_receiver, Some(1)).await.unwrap(); + + assert_request_success( + &mut storage, + request_id, + address, + &output_for_request.bytecode, + &[VerificationProblem::IncorrectMetadata], + ) + .await; } #[test_casing(2, BYTECODE_KINDS)] diff --git a/core/lib/contracts/src/lib.rs b/core/lib/contracts/src/lib.rs index 87f102be39d6..e7cf1508f733 100644 --- a/core/lib/contracts/src/lib.rs +++ b/core/lib/contracts/src/lib.rs @@ -82,7 +82,7 @@ const _FAIL_ON_RECEIVE_CONTRACT_FILE: &str = "contracts/l1-contracts/artifacts/contracts/zksync/dev-contracts/FailOnReceive.sol/FailOnReceive.json"; fn home_path() -> PathBuf { - Workspace::locate().core() + Workspace::locate().root() } fn read_file_to_json_value(path: impl AsRef + std::fmt::Debug) -> Option { diff --git a/core/lib/da_client/src/lib.rs b/core/lib/da_client/src/lib.rs index 7e4a2643a259..dce9c0fa8d1b 100644 --- a/core/lib/da_client/src/lib.rs +++ b/core/lib/da_client/src/lib.rs @@ -23,6 +23,8 @@ pub trait DataAvailabilityClient: Sync + Send + fmt::Debug { /// Returns the maximum size of the blob (in bytes) that can be dispatched. None means no limit. fn blob_size_limit(&self) -> Option; + + async fn balance(&self) -> Result; } impl Clone for Box { diff --git a/core/lib/dal/.sqlx/query-1823e1ac602ce4ba1db06543af9cb2685cda1ae7ecca83062ede7320c3b4a427.json b/core/lib/dal/.sqlx/query-1823e1ac602ce4ba1db06543af9cb2685cda1ae7ecca83062ede7320c3b4a427.json deleted file mode 100644 index 1e20a9151b98..000000000000 --- a/core/lib/dal/.sqlx/query-1823e1ac602ce4ba1db06543af9cb2685cda1ae7ecca83062ede7320c3b4a427.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO\n contracts_verification_info (address, verification_info)\n VALUES\n ($1, $2)\n ON CONFLICT (address) DO\n UPDATE\n SET\n verification_info = $2\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Bytea", - "Jsonb" - ] - }, - "nullable": [] - }, - "hash": "1823e1ac602ce4ba1db06543af9cb2685cda1ae7ecca83062ede7320c3b4a427" -} diff --git a/core/lib/dal/.sqlx/query-2a2083fd04ebd006eb0aa4e0e5f62f3339768a85aaff9a509901e9f42b09097b.json b/core/lib/dal/.sqlx/query-2a2083fd04ebd006eb0aa4e0e5f62f3339768a85aaff9a509901e9f42b09097b.json deleted file mode 100644 index a713616d582c..000000000000 --- a/core/lib/dal/.sqlx/query-2a2083fd04ebd006eb0aa4e0e5f62f3339768a85aaff9a509901e9f42b09097b.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n pubdata_input\n FROM\n l1_batches\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND data_availability.blob_id IS NULL\n AND pubdata_input IS NOT NULL\n ORDER BY\n number\n LIMIT\n $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "number", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "pubdata_input", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - true - ] - }, - "hash": "2a2083fd04ebd006eb0aa4e0e5f62f3339768a85aaff9a509901e9f42b09097b" -} diff --git a/core/lib/dal/.sqlx/query-2d0c2e9ec4187641baef8a33229bffc78d92adb3c1e3ca60b12163e38c67047e.json b/core/lib/dal/.sqlx/query-2d0c2e9ec4187641baef8a33229bffc78d92adb3c1e3ca60b12163e38c67047e.json deleted file mode 100644 index f61f39e3b0b0..000000000000 --- a/core/lib/dal/.sqlx/query-2d0c2e9ec4187641baef8a33229bffc78d92adb3c1e3ca60b12163e38c67047e.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n COUNT(*) AS \"count!\"\n FROM\n contracts_verification_info\n WHERE\n address = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "count!", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Bytea" - ] - }, - "nullable": [ - null - ] - }, - "hash": "2d0c2e9ec4187641baef8a33229bffc78d92adb3c1e3ca60b12163e38c67047e" -} diff --git a/core/lib/dal/.sqlx/query-349d41c8ce192e82152e9d254c23ed5f1e6eac5b71232c784abd4d4cd8677805.json b/core/lib/dal/.sqlx/query-349d41c8ce192e82152e9d254c23ed5f1e6eac5b71232c784abd4d4cd8677805.json new file mode 100644 index 000000000000..2de71e3d1ab5 --- /dev/null +++ b/core/lib/dal/.sqlx/query-349d41c8ce192e82152e9d254c23ed5f1e6eac5b71232c784abd4d4cd8677805.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO\n contract_verification_info_v2 (\n initial_contract_addr,\n bytecode_keccak256,\n bytecode_without_metadata_keccak256,\n verification_info\n )\n VALUES\n ($1, $2, $3, $4)\n ON CONFLICT (initial_contract_addr) DO\n UPDATE\n SET\n bytecode_keccak256 = $2,\n bytecode_without_metadata_keccak256 = $3,\n verification_info = $4\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Bytea", + "Bytea", + "Bytea", + "Jsonb" + ] + }, + "nullable": [] + }, + "hash": "349d41c8ce192e82152e9d254c23ed5f1e6eac5b71232c784abd4d4cd8677805" +} diff --git a/core/lib/dal/.sqlx/query-668cf72b78c6071340143ba9498046b7820e39b63ed4f98bcaa3b3f305cbe576.json b/core/lib/dal/.sqlx/query-668cf72b78c6071340143ba9498046b7820e39b63ed4f98bcaa3b3f305cbe576.json new file mode 100644 index 000000000000..9dffecdc4c19 --- /dev/null +++ b/core/lib/dal/.sqlx/query-668cf72b78c6071340143ba9498046b7820e39b63ed4f98bcaa3b3f305cbe576.json @@ -0,0 +1,26 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n (SELECT COUNT(*) FROM contracts_verification_info) AS count_v1,\n (SELECT COUNT(*) FROM contract_verification_info_v2) AS count_v2\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "count_v1", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "count_v2", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + null + ] + }, + "hash": "668cf72b78c6071340143ba9498046b7820e39b63ed4f98bcaa3b3f305cbe576" +} diff --git a/core/lib/dal/.sqlx/query-6cb50a8fbe1341ba7ea496bb0f2072dcee6e6f8439e6b43eebd6df5563a4d0b9.json b/core/lib/dal/.sqlx/query-6cb50a8fbe1341ba7ea496bb0f2072dcee6e6f8439e6b43eebd6df5563a4d0b9.json new file mode 100644 index 000000000000..a78dcf480064 --- /dev/null +++ b/core/lib/dal/.sqlx/query-6cb50a8fbe1341ba7ea496bb0f2072dcee6e6f8439e6b43eebd6df5563a4d0b9.json @@ -0,0 +1,35 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n verification_info,\n bytecode_keccak256,\n bytecode_without_metadata_keccak256\n FROM\n contract_verification_info_v2\n WHERE\n bytecode_keccak256 = $1\n OR\n (\n bytecode_without_metadata_keccak256 IS NOT null\n AND bytecode_without_metadata_keccak256 = $2\n )\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "verification_info", + "type_info": "Jsonb" + }, + { + "ordinal": 1, + "name": "bytecode_keccak256", + "type_info": "Bytea" + }, + { + "ordinal": 2, + "name": "bytecode_without_metadata_keccak256", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Bytea", + "Bytea" + ] + }, + "nullable": [ + false, + false, + false + ] + }, + "hash": "6cb50a8fbe1341ba7ea496bb0f2072dcee6e6f8439e6b43eebd6df5563a4d0b9" +} diff --git a/core/lib/dal/.sqlx/query-8435ed4ee2a9b962116ecfa522f4ba52c9a0e64d1badc39cc2fef29b1468621a.json b/core/lib/dal/.sqlx/query-970c457cc4513615d9bb6ecd6f1a69128b9f77d7ce3b898e44c497dc56a40149.json similarity index 67% rename from core/lib/dal/.sqlx/query-8435ed4ee2a9b962116ecfa522f4ba52c9a0e64d1badc39cc2fef29b1468621a.json rename to core/lib/dal/.sqlx/query-970c457cc4513615d9bb6ecd6f1a69128b9f77d7ce3b898e44c497dc56a40149.json index df856b977026..d0b576bfa688 100644 --- a/core/lib/dal/.sqlx/query-8435ed4ee2a9b962116ecfa522f4ba52c9a0e64d1badc39cc2fef29b1468621a.json +++ b/core/lib/dal/.sqlx/query-970c457cc4513615d9bb6ecd6f1a69128b9f77d7ce3b898e44c497dc56a40149.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n number,\n timestamp,\n protocol_version,\n fee_address,\n l1_gas_price,\n l2_fair_gas_price,\n fair_pubdata_price\n FROM\n l1_batches\n WHERE\n NOT is_sealed\n ", + "query": "\n SELECT\n number,\n timestamp,\n protocol_version,\n fee_address,\n l1_gas_price,\n l2_fair_gas_price,\n fair_pubdata_price\n FROM (\n SELECT\n number,\n timestamp,\n protocol_version,\n fee_address,\n l1_gas_price,\n l2_fair_gas_price,\n fair_pubdata_price,\n is_sealed\n FROM l1_batches\n ORDER BY number DESC\n LIMIT 1\n ) AS u\n WHERE NOT is_sealed\n ", "describe": { "columns": [ { @@ -52,5 +52,5 @@ false ] }, - "hash": "8435ed4ee2a9b962116ecfa522f4ba52c9a0e64d1badc39cc2fef29b1468621a" + "hash": "970c457cc4513615d9bb6ecd6f1a69128b9f77d7ce3b898e44c497dc56a40149" } diff --git a/core/lib/dal/.sqlx/query-a331b209eafd82595ad75e24135989ff52100e6a93537c35961e62268d7cd26e.json b/core/lib/dal/.sqlx/query-a331b209eafd82595ad75e24135989ff52100e6a93537c35961e62268d7cd26e.json new file mode 100644 index 000000000000..7d2121d708f3 --- /dev/null +++ b/core/lib/dal/.sqlx/query-a331b209eafd82595ad75e24135989ff52100e6a93537c35961e62268d7cd26e.json @@ -0,0 +1,29 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n address,\n verification_info::text AS verification_info\n FROM\n contracts_verification_info\n WHERE address > $1\n ORDER BY\n address\n LIMIT $2\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "address", + "type_info": "Bytea" + }, + { + "ordinal": 1, + "name": "verification_info", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Bytea", + "Int8" + ] + }, + "nullable": [ + false, + null + ] + }, + "hash": "a331b209eafd82595ad75e24135989ff52100e6a93537c35961e62268d7cd26e" +} diff --git a/core/lib/dal/.sqlx/query-ca2c63a0e25406eec4e92a7cfda80a651e28abb3dd3582211ceb6b2bb8009258.json b/core/lib/dal/.sqlx/query-ca2c63a0e25406eec4e92a7cfda80a651e28abb3dd3582211ceb6b2bb8009258.json new file mode 100644 index 000000000000..2708c5b78701 --- /dev/null +++ b/core/lib/dal/.sqlx/query-ca2c63a0e25406eec4e92a7cfda80a651e28abb3dd3582211ceb6b2bb8009258.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n COUNT(*)\n FROM\n contract_verification_info_v2 v2\n JOIN contracts_verification_info v1 ON initial_contract_addr = address\n WHERE v1.verification_info::text != v2.verification_info::text\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "count", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null + ] + }, + "hash": "ca2c63a0e25406eec4e92a7cfda80a651e28abb3dd3582211ceb6b2bb8009258" +} diff --git a/core/lib/dal/.sqlx/query-daa2ad4ebde17808e059aa6bcf148743ffed494316750be3b0ffb10b2fc09e93.json b/core/lib/dal/.sqlx/query-daa2ad4ebde17808e059aa6bcf148743ffed494316750be3b0ffb10b2fc09e93.json new file mode 100644 index 000000000000..fd279a570be9 --- /dev/null +++ b/core/lib/dal/.sqlx/query-daa2ad4ebde17808e059aa6bcf148743ffed494316750be3b0ffb10b2fc09e93.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n verification_info\n FROM\n contract_verification_info_v2\n WHERE\n initial_contract_addr = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "verification_info", + "type_info": "Jsonb" + } + ], + "parameters": { + "Left": [ + "Bytea" + ] + }, + "nullable": [ + false + ] + }, + "hash": "daa2ad4ebde17808e059aa6bcf148743ffed494316750be3b0ffb10b2fc09e93" +} diff --git a/core/lib/dal/.sqlx/query-f2eeb448a856b9e57bcc2a724791fb0ee6299fddc9f89cf70c5b69c7182f0a54.json b/core/lib/dal/.sqlx/query-f2eeb448a856b9e57bcc2a724791fb0ee6299fddc9f89cf70c5b69c7182f0a54.json new file mode 100644 index 000000000000..bba0056a5ffe --- /dev/null +++ b/core/lib/dal/.sqlx/query-f2eeb448a856b9e57bcc2a724791fb0ee6299fddc9f89cf70c5b69c7182f0a54.json @@ -0,0 +1,34 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n number,\n pubdata_input,\n sealed_at\n FROM\n l1_batches\n LEFT JOIN\n data_availability\n ON data_availability.l1_batch_number = l1_batches.number\n WHERE\n eth_commit_tx_id IS NULL\n AND number != 0\n AND data_availability.blob_id IS NULL\n AND pubdata_input IS NOT NULL\n AND sealed_at IS NOT NULL\n ORDER BY\n number\n LIMIT\n $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "number", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "pubdata_input", + "type_info": "Bytea" + }, + { + "ordinal": 2, + "name": "sealed_at", + "type_info": "Timestamp" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + true, + true + ] + }, + "hash": "f2eeb448a856b9e57bcc2a724791fb0ee6299fddc9f89cf70c5b69c7182f0a54" +} diff --git a/core/lib/dal/Cargo.toml b/core/lib/dal/Cargo.toml index 4b093dd181bb..80cd955ff298 100644 --- a/core/lib/dal/Cargo.toml +++ b/core/lib/dal/Cargo.toml @@ -53,6 +53,7 @@ hex.workspace = true strum = { workspace = true, features = ["derive"] } tracing.workspace = true chrono = { workspace = true, features = ["serde"] } +rayon.workspace = true [dev-dependencies] zksync_test_contracts.workspace = true diff --git a/core/lib/dal/migrations/20250122102800_contract-verifier-new-schema.down.sql b/core/lib/dal/migrations/20250122102800_contract-verifier-new-schema.down.sql new file mode 100644 index 000000000000..03c94eab5f61 --- /dev/null +++ b/core/lib/dal/migrations/20250122102800_contract-verifier-new-schema.down.sql @@ -0,0 +1,3 @@ +DROP INDEX IF EXISTS contract_verification_info_v2_bytecode_keccak256_idx; +DROP INDEX IF EXISTS contract_verification_info_v2_bytecode_without_metadata_keccak256_idx; +DROP TABLE IF EXISTS contract_verification_info_v2; diff --git a/core/lib/dal/migrations/20250122102800_contract-verifier-new-schema.up.sql b/core/lib/dal/migrations/20250122102800_contract-verifier-new-schema.up.sql new file mode 100644 index 000000000000..c7eee9063221 --- /dev/null +++ b/core/lib/dal/migrations/20250122102800_contract-verifier-new-schema.up.sql @@ -0,0 +1,13 @@ +CREATE TABLE IF NOT EXISTS contract_verification_info_v2 ( + initial_contract_addr BYTEA NOT NULL PRIMARY KEY, + bytecode_keccak256 BYTEA NOT NULL, + bytecode_without_metadata_keccak256 BYTEA NOT NULL, + verification_info JSONB NOT NULL, + + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- Add hash indexes for hash columns +CREATE INDEX IF NOT EXISTS contract_verification_info_v2_bytecode_keccak256_idx ON contract_verification_info_v2 (bytecode_keccak256); +CREATE INDEX IF NOT EXISTS contract_verification_info_v2_bytecode_without_metadata_keccak256_idx ON contract_verification_info_v2 (bytecode_without_metadata_keccak256); diff --git a/core/lib/dal/src/blocks_dal.rs b/core/lib/dal/src/blocks_dal.rs index f39a9c582df9..7b2f2e33fe2a 100644 --- a/core/lib/dal/src/blocks_dal.rs +++ b/core/lib/dal/src/blocks_dal.rs @@ -835,10 +835,21 @@ impl BlocksDal<'_, '_> { l1_gas_price, l2_fair_gas_price, fair_pubdata_price - FROM - l1_batches - WHERE - NOT is_sealed + FROM ( + SELECT + number, + timestamp, + protocol_version, + fee_address, + l1_gas_price, + l2_fair_gas_price, + fair_pubdata_price, + is_sealed + FROM l1_batches + ORDER BY number DESC + LIMIT 1 + ) AS u + WHERE NOT is_sealed "#, ) .instrument("get_unsealed_l1_batch") diff --git a/core/lib/dal/src/consensus_dal/mod.rs b/core/lib/dal/src/consensus_dal/mod.rs index 7f3bcd1166ad..e6058e86b47d 100644 --- a/core/lib/dal/src/consensus_dal/mod.rs +++ b/core/lib/dal/src/consensus_dal/mod.rs @@ -234,7 +234,6 @@ impl ConsensusDal<'_, '_> { protocol_version: old.genesis.protocol_version, validators: old.genesis.validators.clone(), - attesters: old.genesis.attesters.clone(), leader_selection: old.genesis.leader_selection.clone(), } .with_hash(), diff --git a/core/lib/dal/src/consensus_dal/tests.rs b/core/lib/dal/src/consensus_dal/tests.rs index 694abc8508b6..4b4c5f7b3821 100644 --- a/core/lib/dal/src/consensus_dal/tests.rs +++ b/core/lib/dal/src/consensus_dal/tests.rs @@ -1,17 +1,9 @@ use rand::Rng as _; -use zksync_consensus_roles::{attester, validator}; +use zksync_consensus_roles::validator; use zksync_consensus_storage::ReplicaState; -use zksync_types::{ - block::L1BatchTreeData, - commitment::{L1BatchCommitmentArtifacts, L1BatchCommitmentHash}, - ProtocolVersion, -}; use super::*; -use crate::{ - tests::{create_l1_batch_header, create_l2_block_header}, - ConnectionPool, Core, CoreDal, -}; +use crate::{ConnectionPool, Core, CoreDal}; #[tokio::test] async fn replica_state_read_write() { @@ -52,138 +44,141 @@ async fn replica_state_read_write() { } } -#[tokio::test] -async fn test_batch_certificate() { - let rng = &mut rand::thread_rng(); - let setup = validator::testonly::Setup::new(rng, 3); - let pool = ConnectionPool::::test_pool().await; - let mut conn = pool.connection().await.unwrap(); - let cfg = GlobalConfig { - genesis: setup.genesis.clone(), - registry_address: Some(rng.gen()), - seed_peers: [].into(), - }; - conn.consensus_dal() - .try_update_global_config(&cfg) - .await - .unwrap(); +// NOTE: This test is disabled since we are going to remove L1 batches. Most likely +// we will remove all the attester related code as well, but keeping this until +// we are sure. +// #[tokio::test] +// async fn test_batch_certificate() { +// let rng = &mut rand::thread_rng(); +// let setup = validator::testonly::Setup::new(rng, 3); +// let pool = ConnectionPool::::test_pool().await; +// let mut conn = pool.connection().await.unwrap(); +// let cfg = GlobalConfig { +// genesis: setup.genesis.clone(), +// registry_address: Some(rng.gen()), +// seed_peers: [].into(), +// }; +// conn.consensus_dal() +// .try_update_global_config(&cfg) +// .await +// .unwrap(); - let make_cert = |number: attester::BatchNumber, hash: attester::BatchHash| { - let m = attester::Batch { - genesis: setup.genesis.hash(), - hash, - number, - }; - let mut sigs = attester::MultiSig::default(); - for k in &setup.attester_keys { - sigs.add(k.public(), k.sign_msg(m.clone()).sig); - } - attester::BatchQC { - message: m, - signatures: sigs, - } - }; +// let make_cert = |number: attester::BatchNumber, hash: attester::BatchHash| { +// let m = attester::Batch { +// genesis: setup.genesis.hash(), +// hash, +// number, +// }; +// let mut sigs = attester::MultiSig::default(); +// for k in &setup.attester_keys { +// sigs.add(k.public(), k.sign_msg(m.clone()).sig); +// } +// attester::BatchQC { +// message: m, +// signatures: sigs, +// } +// }; - // Required for inserting l2 blocks - conn.protocol_versions_dal() - .save_protocol_version_with_tx(&ProtocolVersion::default()) - .await - .unwrap(); +// // Required for inserting l2 blocks +// conn.protocol_versions_dal() +// .save_protocol_version_with_tx(&ProtocolVersion::default()) +// .await +// .unwrap(); - // Insert some mock L2 blocks and L1 batches - let mut block_number = 0; - let mut batch_number = 0; - for _ in 0..3 { - for _ in 0..3 { - block_number += 1; - let l2_block = create_l2_block_header(block_number); - conn.blocks_dal().insert_l2_block(&l2_block).await.unwrap(); - } - batch_number += 1; - let l1_batch = create_l1_batch_header(batch_number); - conn.blocks_dal() - .insert_mock_l1_batch(&l1_batch) - .await - .unwrap(); - conn.blocks_dal() - .save_l1_batch_tree_data( - l1_batch.number, - &L1BatchTreeData { - hash: rng.gen(), - rollup_last_leaf_index: rng.gen(), - }, - ) - .await - .unwrap(); - conn.blocks_dal() - .save_l1_batch_commitment_artifacts( - l1_batch.number, - &L1BatchCommitmentArtifacts { - commitment_hash: L1BatchCommitmentHash { - pass_through_data: rng.gen(), - aux_output: rng.gen(), - meta_parameters: rng.gen(), - commitment: rng.gen(), - }, - l2_l1_merkle_root: rng.gen(), - compressed_state_diffs: None, - compressed_initial_writes: None, - compressed_repeated_writes: None, - zkporter_is_available: false, - aux_commitments: None, - aggregation_root: rng.gen(), - local_root: rng.gen(), - state_diff_hash: rng.gen(), - }, - ) - .await - .unwrap(); - conn.blocks_dal() - .mark_l2_blocks_as_executed_in_l1_batch(l1_batch.number) - .await - .unwrap(); - } +// // Insert some mock L2 blocks and L1 batches +// let mut block_number = 0; +// let mut batch_number = 0; +// for _ in 0..3 { +// for _ in 0..3 { +// block_number += 1; +// let l2_block = create_l2_block_header(block_number); +// conn.blocks_dal().insert_l2_block(&l2_block).await.unwrap(); +// } +// batch_number += 1; +// let l1_batch = create_l1_batch_header(batch_number); +// conn.blocks_dal() +// .insert_mock_l1_batch(&l1_batch) +// .await +// .unwrap(); +// conn.blocks_dal() +// .save_l1_batch_tree_data( +// l1_batch.number, +// &L1BatchTreeData { +// hash: rng.gen(), +// rollup_last_leaf_index: rng.gen(), +// }, +// ) +// .await +// .unwrap(); +// conn.blocks_dal() +// .save_l1_batch_commitment_artifacts( +// l1_batch.number, +// &L1BatchCommitmentArtifacts { +// commitment_hash: L1BatchCommitmentHash { +// pass_through_data: rng.gen(), +// aux_output: rng.gen(), +// meta_parameters: rng.gen(), +// commitment: rng.gen(), +// }, +// l2_l1_merkle_root: rng.gen(), +// compressed_state_diffs: None, +// compressed_initial_writes: None, +// compressed_repeated_writes: None, +// zkporter_is_available: false, +// aux_commitments: None, +// aggregation_root: rng.gen(), +// local_root: rng.gen(), +// state_diff_hash: rng.gen(), +// }, +// ) +// .await +// .unwrap(); +// conn.blocks_dal() +// .mark_l2_blocks_as_executed_in_l1_batch(l1_batch.number) +// .await +// .unwrap(); +// } - let n = attester::BatchNumber(batch_number.into()); +// let n = attester::BatchNumber(batch_number.into()); - // Insert a batch certificate for the last L1 batch. - let hash = batch_hash(&conn.consensus_dal().batch_info(n).await.unwrap().unwrap()); - let want = make_cert(n, hash); - conn.consensus_dal() - .upsert_attester_committee(n, setup.genesis.attesters.as_ref().unwrap()) - .await - .unwrap(); - conn.consensus_dal() - .insert_batch_certificate(&want) - .await - .unwrap(); +// // Insert a batch certificate for the last L1 batch. +// let hash = batch_hash(&conn.consensus_dal().batch_info(n).await.unwrap().unwrap()); +// let want = make_cert(n, hash); +// conn.consensus_dal() +// .upsert_attester_committee(n, setup.genesis.attesters.as_ref().unwrap()) +// .await +// .unwrap(); +// conn.consensus_dal() +// .insert_batch_certificate(&want) +// .await +// .unwrap(); - // Reinserting a cert should fail. - assert!(conn - .consensus_dal() - .insert_batch_certificate(&make_cert(n, hash)) - .await - .is_err()); +// // Reinserting a cert should fail. +// assert!(conn +// .consensus_dal() +// .insert_batch_certificate(&make_cert(n, hash)) +// .await +// .is_err()); - // Retrieve the latest certificate. - let got_n = conn - .consensus_dal() - .last_batch_certificate_number() - .await - .unwrap() - .unwrap(); - let got = conn - .consensus_dal() - .batch_certificate(got_n) - .await - .unwrap() - .unwrap(); - assert_eq!(got, want); +// // Retrieve the latest certificate. +// let got_n = conn +// .consensus_dal() +// .last_batch_certificate_number() +// .await +// .unwrap() +// .unwrap(); +// let got = conn +// .consensus_dal() +// .batch_certificate(got_n) +// .await +// .unwrap() +// .unwrap(); +// assert_eq!(got, want); - // Try insert batch certificate for non-existing batch - assert!(conn - .consensus_dal() - .insert_batch_certificate(&make_cert(n.next(), rng.gen())) - .await - .is_err()); -} +// // Try insert batch certificate for non-existing batch +// assert!(conn +// .consensus_dal() +// .insert_batch_certificate(&make_cert(n.next(), rng.gen())) +// .await +// .is_err()); +// } diff --git a/core/lib/dal/src/contract_verification_dal.rs b/core/lib/dal/src/contract_verification_dal.rs index 57bea5392cf8..9125f972c55b 100644 --- a/core/lib/dal/src/contract_verification_dal.rs +++ b/core/lib/dal/src/contract_verification_dal.rs @@ -5,13 +5,20 @@ use std::{ time::Duration, }; +use rayon::prelude::*; use sqlx::postgres::types::PgInterval; -use zksync_db_connection::{error::SqlxContext, instrument::InstrumentExt}; +use zksync_db_connection::{ + error::SqlxContext, + instrument::{CopyStatement, InstrumentExt}, +}; use zksync_types::{ address_to_h256, - contract_verification_api::{ - VerificationIncomingRequest, VerificationInfo, VerificationRequest, - VerificationRequestStatus, + contract_verification::{ + api::{ + VerificationIncomingRequest, VerificationInfo, VerificationRequest, + VerificationRequestStatus, + }, + contract_identifier::ContractIdentifier, }, web3, Address, CONTRACT_DEPLOYER_ADDRESS, H256, }; @@ -188,6 +195,8 @@ impl ContractVerificationDal<'_, '_> { pub async fn save_verification_info( &mut self, verification_info: VerificationInfo, + bytecode_keccak256: H256, + bytecode_without_metadata_keccak256: H256, ) -> DalResult<()> { let mut transaction = self.storage.start_transaction().await?; let id = verification_info.request.id; @@ -216,15 +225,24 @@ impl ContractVerificationDal<'_, '_> { sqlx::query!( r#" INSERT INTO - contracts_verification_info (address, verification_info) + contract_verification_info_v2 ( + initial_contract_addr, + bytecode_keccak256, + bytecode_without_metadata_keccak256, + verification_info + ) VALUES - ($1, $2) - ON CONFLICT (address) DO + ($1, $2, $3, $4) + ON CONFLICT (initial_contract_addr) DO UPDATE SET - verification_info = $2 + bytecode_keccak256 = $2, + bytecode_without_metadata_keccak256 = $3, + verification_info = $4 "#, address.as_bytes(), + bytecode_keccak256.as_bytes(), + bytecode_without_metadata_keccak256.as_bytes(), &verification_info_json ) .instrument("save_verification_info#insert") @@ -376,27 +394,6 @@ impl ContractVerificationDal<'_, '_> { .await } - /// Returns true if the contract has a stored contracts_verification_info. - pub async fn is_contract_verified(&mut self, address: Address) -> DalResult { - let count = sqlx::query!( - r#" - SELECT - COUNT(*) AS "count!" - FROM - contracts_verification_info - WHERE - address = $1 - "#, - address.as_bytes() - ) - .instrument("is_contract_verified") - .with_arg("address", &address) - .fetch_one(self.storage) - .await? - .count; - Ok(count > 0) - } - async fn get_compiler_versions(&mut self, compiler: Compiler) -> DalResult> { let compiler = format!("{compiler}"); let versions: Vec<_> = sqlx::query!( @@ -537,6 +534,29 @@ impl ContractVerificationDal<'_, '_> { pub async fn get_contract_verification_info( &mut self, address: Address, + ) -> anyhow::Result> { + // Do everything in a read-only transaction for a consistent view. + let mut transaction = self + .storage + .transaction_builder()? + .set_readonly() + .build() + .await?; + + let mut dal = ContractVerificationDal { + storage: &mut transaction, + }; + let info = if dal.is_verification_info_migration_performed().await? { + dal.get_contract_verification_info_v2(address).await? + } else { + dal.get_contract_verification_info_v1(address).await? + }; + Ok(info) + } + + async fn get_contract_verification_info_v1( + &mut self, + address: Address, ) -> DalResult> { Ok(sqlx::query!( r#" @@ -560,6 +580,236 @@ impl ContractVerificationDal<'_, '_> { .await? .flatten()) } + + async fn get_contract_verification_info_v2( + &mut self, + address: Address, + ) -> anyhow::Result> { + Ok(sqlx::query!( + r#" + SELECT + verification_info + FROM + contract_verification_info_v2 + WHERE + initial_contract_addr = $1 + "#, + address.as_bytes(), + ) + .try_map(|row| { + serde_json::from_value(row.verification_info).decode_column("verification_info") + }) + .instrument("get_contract_verification_info_v2") + .with_arg("address", &address) + .fetch_optional(self.storage) + .await? + .flatten()) + } + + pub async fn get_partial_match_verification_info( + &mut self, + bytecode_keccak256: H256, + bytecode_without_metadata_keccak256: H256, + ) -> DalResult> { + sqlx::query!( + r#" + SELECT + verification_info, + bytecode_keccak256, + bytecode_without_metadata_keccak256 + FROM + contract_verification_info_v2 + WHERE + bytecode_keccak256 = $1 + OR + ( + bytecode_without_metadata_keccak256 IS NOT null + AND bytecode_without_metadata_keccak256 = $2 + ) + "#, + bytecode_keccak256.as_bytes(), + bytecode_without_metadata_keccak256.as_bytes() + ) + .try_map(|row| { + let info = serde_json::from_value::(row.verification_info) + .decode_column("verification_info")?; + let bytecode_keccak256 = H256::from_slice(&row.bytecode_keccak256); + let bytecode_without_metadata_keccak256 = + H256::from_slice(&row.bytecode_without_metadata_keccak256); + Ok(( + info, + bytecode_keccak256, + bytecode_without_metadata_keccak256, + )) + }) + .instrument("get_partial_match_verification_info") + .with_arg("bytecode_keccak256", &bytecode_keccak256) + .with_arg( + "bytecode_without_metadata_keccak256", + &bytecode_without_metadata_keccak256, + ) + .fetch_optional(self.storage) + .await + } + + /// Checks if migration from `contracts_verification_info` to `contract_verification_info_v2` is performed + /// by checking if the latter has more or equal number of rows. + pub async fn is_verification_info_migration_performed(&mut self) -> DalResult { + let row = sqlx::query!( + r#" + SELECT + (SELECT COUNT(*) FROM contracts_verification_info) AS count_v1, + (SELECT COUNT(*) FROM contract_verification_info_v2) AS count_v2 + "#, + ) + .instrument("is_verification_info_migration_performed") + .fetch_one(self.storage) + .await?; + + Ok(row.count_v2 >= row.count_v1) + } + + pub async fn perform_verification_info_migration( + &mut self, + batch_size: usize, + ) -> anyhow::Result<()> { + // We use a long-running transaction, since the migration is one-time and during it + // no writes are expected to the tables, so locked rows are not a problem. + let mut transaction = self.storage.start_transaction().await?; + + // Offset is a number of already migrated contracts. + let mut offset = 0usize; + let mut cursor = vec![]; + loop { + let cursor_str = format!("0x{}", hex::encode(&cursor)); + + // Fetch JSON as text to avoid roundtrip through `serde_json::Value`, as it's super slow. + let (addresses, verification_infos): (Vec>, Vec) = sqlx::query!( + r#" + SELECT + address, + verification_info::text AS verification_info + FROM + contracts_verification_info + WHERE address > $1 + ORDER BY + address + LIMIT $2 + "#, + &cursor, + batch_size as i64, + ) + .instrument("perform_verification_info_migration#select") + .with_arg("cursor", &cursor_str) + .with_arg("batch_size", &batch_size) + .fetch_all(&mut transaction) + .await? + .into_iter() + .filter_map(|row| row.verification_info.map(|info| (row.address, info))) + .collect(); + + if addresses.is_empty() { + tracing::info!("No more contracts to process"); + break; + } + + tracing::info!( + "Processing {} contracts (processed: {offset}); cursor {cursor_str}", + addresses.len() + ); + + let ids: Vec = (0..addresses.len()) + .into_par_iter() + .map(|idx| { + let address = &addresses[idx]; + let info_json = &verification_infos[idx]; + let verification_info = serde_json::from_str::(info_json) + .unwrap_or_else(|err| { + panic!( + "Malformed data in DB, address {}, data: {info_json}, error: {err}", + hex::encode(address) + ); + }); + ContractIdentifier::from_bytecode( + verification_info.bytecode_marker(), + verification_info.artifacts.deployed_bytecode(), + ) + }) + .collect(); + + let now = chrono::Utc::now().naive_utc().to_string(); + let mut buffer = String::new(); + for idx in 0..addresses.len() { + let address = hex::encode(&addresses[idx]); + let bytecode_keccak256 = hex::encode(ids[idx].bytecode_keccak256); + let bytecode_without_metadata_keccak256 = + hex::encode(ids[idx].bytecode_without_metadata_keccak256); + let verification_info = verification_infos[idx].replace('"', r#""""#); + + let row = format!( + r#"\\x{initial_contract_addr},\\x{bytecode_keccak256},\\x{bytecode_without_metadata_keccak256},"{verification_info}",{created_at},{updated_at}"#, + initial_contract_addr = address, + bytecode_keccak256 = bytecode_keccak256, + bytecode_without_metadata_keccak256 = bytecode_without_metadata_keccak256, + verification_info = verification_info, + created_at = now, + updated_at = now + ); + buffer.push_str(&row); + buffer.push('\n'); + } + + let contracts_len = addresses.len(); + let copy = CopyStatement::new( + "COPY contract_verification_info_v2( + initial_contract_addr, + bytecode_keccak256, + bytecode_without_metadata_keccak256, + verification_info, + created_at, + updated_at + ) FROM STDIN (FORMAT CSV, NULL 'null', DELIMITER ',')", + ) + .instrument("perform_verification_info_migration#copy") + .with_arg("cursor", &cursor_str) + .with_arg("contracts.len", &contracts_len) + .start(&mut transaction) + .await?; + + copy.send(buffer.as_bytes()).await?; + + offset += batch_size; + cursor = addresses.last().unwrap().clone(); + } + + // Sanity check. + tracing::info!("All the rows are migrated, verifying the migration"); + let count_unequal = sqlx::query!( + r#" + SELECT + COUNT(*) + FROM + contract_verification_info_v2 v2 + JOIN contracts_verification_info v1 ON initial_contract_addr = address + WHERE v1.verification_info::text != v2.verification_info::text + "#, + ) + .instrument("is_verification_info_migration_performed") + .fetch_one(&mut transaction) + .await? + .count + .unwrap(); + if count_unequal > 0 { + anyhow::bail!( + "Migration failed: {} rows have different data in the new table", + count_unequal + ); + } + + tracing::info!("Migration is successful, committing the transaction"); + transaction.commit().await?; + Ok(()) + } } #[cfg(test)] @@ -568,7 +818,7 @@ mod tests { use zksync_types::{ bytecode::BytecodeHash, - contract_verification_api::{CompilerVersions, SourceCodeData}, + contract_verification::api::{CompilerVersions, SourceCodeData}, tx::IncludedTxLocation, Execute, L1BatchNumber, L2BlockNumber, ProtocolVersion, }; diff --git a/core/lib/dal/src/data_availability_dal.rs b/core/lib/dal/src/data_availability_dal.rs index 41dd7efe2732..8503cc21f283 100644 --- a/core/lib/dal/src/data_availability_dal.rs +++ b/core/lib/dal/src/data_availability_dal.rs @@ -184,7 +184,8 @@ impl DataAvailabilityDal<'_, '_> { r#" SELECT number, - pubdata_input + pubdata_input, + sealed_at FROM l1_batches LEFT JOIN @@ -195,6 +196,7 @@ impl DataAvailabilityDal<'_, '_> { AND number != 0 AND data_availability.blob_id IS NULL AND pubdata_input IS NOT NULL + AND sealed_at IS NOT NULL ORDER BY number LIMIT @@ -213,6 +215,7 @@ impl DataAvailabilityDal<'_, '_> { // `unwrap` is safe here because we have a `WHERE` clause that filters out `NULL` values pubdata: row.pubdata_input.unwrap(), l1_batch_number: L1BatchNumber(row.number as u32), + sealed_at: row.sealed_at.unwrap().and_utc(), }) .collect()) } diff --git a/core/lib/dal/src/models/storage_data_availability.rs b/core/lib/dal/src/models/storage_data_availability.rs index 2a1b39845e69..cfdbde5ac3a8 100644 --- a/core/lib/dal/src/models/storage_data_availability.rs +++ b/core/lib/dal/src/models/storage_data_availability.rs @@ -1,4 +1,4 @@ -use chrono::NaiveDateTime; +use chrono::{DateTime, NaiveDateTime, Utc}; use zksync_types::{pubdata_da::DataAvailabilityBlob, L1BatchNumber}; /// Represents a blob in the data availability layer. @@ -26,4 +26,5 @@ impl From for DataAvailabilityBlob { pub struct L1BatchDA { pub pubdata: Vec, pub l1_batch_number: L1BatchNumber, + pub sealed_at: DateTime, } diff --git a/core/lib/dal/src/models/storage_verification_request.rs b/core/lib/dal/src/models/storage_verification_request.rs index ae4718e41290..1ea70ed38129 100644 --- a/core/lib/dal/src/models/storage_verification_request.rs +++ b/core/lib/dal/src/models/storage_verification_request.rs @@ -1,5 +1,5 @@ use zksync_types::{ - contract_verification_api::{ + contract_verification::api::{ CompilerType, CompilerVersions, SourceCodeData, VerificationIncomingRequest, VerificationRequest, }, diff --git a/core/lib/l1_contract_interface/src/i_executor/methods/execute_batches.rs b/core/lib/l1_contract_interface/src/i_executor/methods/execute_batches.rs index 649a7ca2b419..5d5494ca62a8 100644 --- a/core/lib/l1_contract_interface/src/i_executor/methods/execute_batches.rs +++ b/core/lib/l1_contract_interface/src/i_executor/methods/execute_batches.rs @@ -1,11 +1,12 @@ use zksync_types::{ commitment::{L1BatchWithMetadata, PriorityOpsMerkleProof}, ethabi::{encode, Token}, + ProtocolVersionId, }; use crate::{ i_executor::structures::{StoredBatchInfo, SUPPORTED_ENCODING_VERSION}, - Tokenizable, Tokenize, + Tokenizable, }; /// Input required to encode `executeBatches` call. @@ -15,11 +16,15 @@ pub struct ExecuteBatches { pub priority_ops_proofs: Vec, } -impl Tokenize for &ExecuteBatches { - fn into_tokens(self) -> Vec { - let protocol_version = self.l1_batches[0].header.protocol_version.unwrap(); +impl ExecuteBatches { + // The encodings of `ExecuteBatches` operations are different depending on the protocol version + // of the underlying chain. + // However, we can send batches with older protocol versions just by changing the encoding. + // This makes the migration simpler. + pub fn encode_for_eth_tx(&self, chain_protocol_version: ProtocolVersionId) -> Vec { + let internal_protocol_version = self.l1_batches[0].header.protocol_version.unwrap(); - if protocol_version.is_pre_gateway() { + if internal_protocol_version.is_pre_gateway() && chain_protocol_version.is_pre_gateway() { vec![Token::Array( self.l1_batches .iter() diff --git a/core/lib/multivm/Cargo.toml b/core/lib/multivm/Cargo.toml index 107a168e305a..325a6f3a99e3 100644 --- a/core/lib/multivm/Cargo.toml +++ b/core/lib/multivm/Cargo.toml @@ -40,5 +40,5 @@ assert_matches.workspace = true pretty_assertions.workspace = true rand.workspace = true test-casing.workspace = true -zksync_test_contracts.workspace = true zksync_eth_signer.workspace = true +zksync_test_contracts.workspace = true diff --git a/core/lib/multivm/src/tracers/call_tracer/mod.rs b/core/lib/multivm/src/tracers/call_tracer/mod.rs index 44f274876032..20beb10642d8 100644 --- a/core/lib/multivm/src/tracers/call_tracer/mod.rs +++ b/core/lib/multivm/src/tracers/call_tracer/mod.rs @@ -17,6 +17,8 @@ pub mod vm_virtual_blocks; #[derive(Debug, Clone)] pub struct CallTracer { stack: Vec, + finished_calls: Vec, + result: Arc>>, max_stack_depth: usize, @@ -41,6 +43,7 @@ impl CallTracer { pub fn new(result: Arc>>) -> Self { Self { stack: vec![], + finished_calls: vec![], result, max_stack_depth: 0, max_near_calls: 0, diff --git a/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs b/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs index ed18a3eca47d..afa02d24f200 100644 --- a/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs +++ b/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs @@ -67,7 +67,9 @@ impl VmTracer for CallTracer { _bootloader_state: &BootloaderState, _stop_reason: VmExecutionStopReason, ) { - self.store_result() + let result = std::mem::take(&mut self.finished_calls); + let cell = self.result.as_ref(); + cell.set(result).unwrap(); } } @@ -191,7 +193,6 @@ impl CallTracer { .farcall .parent_gas .saturating_sub(state.vm_local_state.callstack.current.ergs_remaining as u64); - self.save_output_latest(state, memory, ret_opcode, &mut current_call.farcall); // If there is a parent call, push the current call to it @@ -199,7 +200,7 @@ impl CallTracer { if let Some(parent_call) = self.stack.last_mut() { parent_call.farcall.calls.push(current_call.farcall); } else { - self.push_call_and_update_stats(current_call.farcall, current_call.near_calls_after); + self.finished_calls.push(current_call.farcall); } } } diff --git a/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs b/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs index 5588dd144e95..5ad0ca025937 100644 --- a/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs +++ b/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs @@ -22,8 +22,8 @@ use crate::{ }, }, vm_latest::{ - tracers::utils::{computational_gas_price, get_calldata_page_via_abi, VmHook}, - BootloaderState, SimpleMemory, VmTracer, ZkSyncVmState, + tracers::utils::{computational_gas_price, get_calldata_page_via_abi}, + BootloaderState, SimpleMemory, VmHook, VmTracer, ZkSyncVmState, }, HistoryMode, }; @@ -205,25 +205,25 @@ impl DynTracer> let hook = VmHook::from_opcode_memory(&state, &data, self.vm_version.try_into().unwrap()); let current_mode = self.validation_mode; match (current_mode, hook) { - (ValidationTracerMode::NoValidation, VmHook::AccountValidationEntered) => { + (ValidationTracerMode::NoValidation, Some(VmHook::AccountValidationEntered)) => { // Account validation can be entered when there is no prior validation (i.e. "nested" validations are not allowed) self.validation_mode = ValidationTracerMode::UserTxValidation; } - (ValidationTracerMode::NoValidation, VmHook::PaymasterValidationEntered) => { + (ValidationTracerMode::NoValidation, Some(VmHook::PaymasterValidationEntered)) => { // Paymaster validation can be entered when there is no prior validation (i.e. "nested" validations are not allowed) self.validation_mode = ValidationTracerMode::PaymasterTxValidation; } - (_, VmHook::AccountValidationEntered | VmHook::PaymasterValidationEntered) => { + (_, Some(VmHook::AccountValidationEntered | VmHook::PaymasterValidationEntered)) => { panic!( "Unallowed transition inside the validation tracer. Mode: {:#?}, hook: {:#?}", self.validation_mode, hook ); } - (_, VmHook::NoValidationEntered) => { + (_, Some(VmHook::ValidationExited)) => { // Validation can be always turned off self.validation_mode = ValidationTracerMode::NoValidation; } - (_, VmHook::ValidationStepEndeded) => { + (_, Some(VmHook::ValidationStepEnded)) => { // The validation step has ended. self.should_stop_execution = true; } diff --git a/core/lib/multivm/src/utils/mod.rs b/core/lib/multivm/src/utils/mod.rs index 7bb907efc9b8..825874747682 100644 --- a/core/lib/multivm/src/utils/mod.rs +++ b/core/lib/multivm/src/utils/mod.rs @@ -113,13 +113,13 @@ pub fn adjust_pubdata_price_for_tx( ) -> BatchFeeInput { // If no max base fee was provided, we just use the maximal one for convenience. let max_base_fee = max_base_fee.unwrap_or(U256::MAX); - let desired_gas_per_pubdata = + let bounded_tx_gas_per_pubdata_limit = tx_gas_per_pubdata_limit.min(get_max_gas_per_pubdata_byte(vm_version).into()); let (current_base_fee, current_gas_per_pubdata) = derive_base_fee_and_gas_per_pubdata(batch_fee_input, vm_version); - if U256::from(current_gas_per_pubdata) <= desired_gas_per_pubdata + if U256::from(current_gas_per_pubdata) <= bounded_tx_gas_per_pubdata_limit && U256::from(current_base_fee) <= max_base_fee { // gas per pubdata is already smaller than or equal to `tx_gas_per_pubdata_limit`. @@ -138,8 +138,9 @@ pub fn adjust_pubdata_price_for_tx( // `gasPerPubdata = ceil(17 * l1gasprice / fair_l2_gas_price)` // `gasPerPubdata <= 17 * l1gasprice / fair_l2_gas_price + 1` // `fair_l2_gas_price(gasPerPubdata - 1) / 17 <= l1gasprice` - let new_l1_gas_price = - fair_l2_gas_price * (desired_gas_per_pubdata - U256::from(1u32)) / U256::from(17); + let new_l1_gas_price = fair_l2_gas_price + * bounded_tx_gas_per_pubdata_limit.saturating_sub(U256::from(1u32)) + / U256::from(17); BatchFeeInput::L1Pegged(L1PeggedBatchFeeModelInput { l1_gas_price: new_l1_gas_price.as_u64(), @@ -154,11 +155,14 @@ pub fn adjust_pubdata_price_for_tx( current_l2_fair_gas_price }; + // We want to adjust gas per pubdata to be min(bounded_tx_gas_per_pubdata_limit, current_gas_per_pubdata). + let desired_gas_per_pubdata = + bounded_tx_gas_per_pubdata_limit.min(U256::from(current_gas_per_pubdata)); // `gasPerPubdata = ceil(fair_pubdata_price / fair_l2_gas_price)` // `gasPerPubdata <= fair_pubdata_price / fair_l2_gas_price + 1` // `fair_l2_gas_price(gasPerPubdata - 1) <= fair_pubdata_price` let new_fair_pubdata_price = - fair_l2_gas_price * (desired_gas_per_pubdata - U256::from(1u32)); + fair_l2_gas_price * desired_gas_per_pubdata.saturating_sub(U256::from(1u32)); BatchFeeInput::PubdataIndependent(PubdataIndependentBatchFeeModelInput { fair_pubdata_price: new_fair_pubdata_price.as_u64(), diff --git a/core/lib/multivm/src/versions/shadow/mod.rs b/core/lib/multivm/src/versions/shadow/mod.rs index 1ad5bdba5a7b..ee1eb02b0dd5 100644 --- a/core/lib/multivm/src/versions/shadow/mod.rs +++ b/core/lib/multivm/src/versions/shadow/mod.rs @@ -25,7 +25,7 @@ use crate::{ mod tests; type ReferenceVm = vm_latest::Vm, HistoryEnabled>; -type ShadowedFastVm = crate::vm_instance::ShadowedFastVm; +type ShadowedFastVm = crate::vm_instance::ShadowedFastVm; fn hash_block(block_env: L2BlockEnv, tx_hashes: &[H256]) -> H256 { let mut hasher = L2BlockHasher::new( diff --git a/core/lib/multivm/src/versions/shadow/tests.rs b/core/lib/multivm/src/versions/shadow/tests.rs index 2d3dd5d3ae30..dc7417ad1259 100644 --- a/core/lib/multivm/src/versions/shadow/tests.rs +++ b/core/lib/multivm/src/versions/shadow/tests.rs @@ -1,20 +1,30 @@ //! Unit tests from the `testonly` test suite. -use std::{collections::HashSet, rc::Rc}; +use std::{collections::HashSet, fmt, rc::Rc}; use zksync_types::{writes::StateDiffRecord, StorageKey, Transaction, H256, U256}; +use zksync_vm2::interface::Tracer; +use zksync_vm_interface::{ + utils::{CheckDivergence, DivergenceErrors}, + Call, +}; use super::ShadowedFastVm; use crate::{ interface::{ pubdata::{PubdataBuilder, PubdataInput}, + storage::InMemoryStorage, utils::{ShadowMut, ShadowRef}, CurrentExecutionState, L2BlockEnv, VmExecutionResultAndLogs, }, - versions::testonly::TestedVm, + versions::testonly::{TestedVm, TestedVmWithCallTracer}, + vm_fast, }; -impl TestedVm for ShadowedFastVm { +impl TestedVm for ShadowedFastVm +where + Tr: Tracer + Default + fmt::Debug + 'static, +{ type StateDump = (); fn dump_state(&self) -> Self::StateDump { @@ -135,6 +145,44 @@ impl TestedVm for ShadowedFastVm { } } +#[derive(Debug)] +struct ExecutionResultAndTraces { + result: VmExecutionResultAndLogs, + traces: Vec, +} + +impl From<(VmExecutionResultAndLogs, Vec)> for ExecutionResultAndTraces { + fn from((result, traces): (VmExecutionResultAndLogs, Vec)) -> Self { + Self { result, traces } + } +} + +impl From for (VmExecutionResultAndLogs, Vec) { + fn from(value: ExecutionResultAndTraces) -> Self { + (value.result, value.traces) + } +} + +impl CheckDivergence for ExecutionResultAndTraces { + fn check_divergence(&self, other: &Self) -> DivergenceErrors { + let mut errors = self.result.check_divergence(&other.result); + errors.extend(self.traces.check_divergence(&other.traces)); + errors + } +} + +impl TestedVmWithCallTracer for ShadowedFastVm { + fn inspect_with_call_tracer(&mut self) -> (VmExecutionResultAndLogs, Vec) { + self.get_custom_mut("inspect_with_call_tracer", |r| { + ExecutionResultAndTraces::from(match r { + ShadowMut::Main(vm) => vm.inspect_with_call_tracer(), + ShadowMut::Shadow(vm) => vm.inspect_with_call_tracer(), + }) + }) + .into() + } +} + mod block_tip { use crate::versions::testonly::block_tip::*; @@ -167,6 +215,40 @@ mod bytecode_publishing { } } +mod call_tracer { + use crate::versions::testonly::call_tracer::*; + + #[test] + fn basic_behavior() { + test_basic_behavior::>(); + } + + #[test] + fn transfer() { + test_transfer::>(); + } + + #[test] + fn reverted_tx() { + test_reverted_tx::>(); + } + + #[test] + fn reverted_deployment() { + test_reverted_deployment_tx::>(); + } + + #[test] + fn out_of_gas() { + test_out_of_gas::>(); + } + + #[test] + fn recursive_tx() { + test_recursive_tx::>(); + } +} + mod circuits { use crate::versions::testonly::circuits::*; diff --git a/core/lib/multivm/src/versions/testonly/call_tracer.rs b/core/lib/multivm/src/versions/testonly/call_tracer.rs new file mode 100644 index 000000000000..0e86cebec46e --- /dev/null +++ b/core/lib/multivm/src/versions/testonly/call_tracer.rs @@ -0,0 +1,292 @@ +//! Call tracer tests. These tests are special in the sense that it's too unreliable to keep fixtures +//! (since they can be invalidated by unrelated changes in system contracts, e.g. by changing consumed gas costs). + +use assert_matches::assert_matches; +use ethabi::Token; +use zksync_system_constants::MSG_VALUE_SIMULATOR_ADDRESS; +use zksync_test_contracts::{Account, LoadnextContractExecutionParams, TestContract, TxType}; +use zksync_types::{ + fee::Fee, utils::deployed_address_create, zk_evm_types::FarCallOpcode, Address, Execute, +}; + +use super::{ContractToDeploy, TestedVmWithCallTracer, VmTester, VmTesterBuilder}; +use crate::{ + interface::{Call, CallType, ExecutionResult, TxExecutionMode}, + vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT, +}; + +fn check_call(call: &Call) { + assert!(call.gas_used < call.gas); + assert!(call.gas_used > call.calls.iter().map(|call| call.gas_used).sum::()); + + for subcall in &call.calls { + if subcall.r#type != CallType::Call(FarCallOpcode::Mimic) { + pretty_assertions::assert_eq!(call.to, subcall.from); + } + check_call(subcall); + } +} + +fn extract_single_call(calls: &[Call], filter: impl Fn(&Call) -> bool) -> &Call { + fn walk<'a>( + matching_call: &mut Option<&'a Call>, + calls: &'a [Call], + filter: &impl Fn(&Call) -> bool, + ) { + for call in calls { + if filter(call) { + if let Some(prev_call) = matching_call { + panic!("Multiple call match filter: {prev_call:?}, {call:?}"); + } + *matching_call = Some(call); + } + walk(matching_call, &call.calls, filter); + } + } + + let mut matching_call = None; + walk(&mut matching_call, calls, &filter); + matching_call.expect("no calls match the filter") +} + +pub(crate) fn test_basic_behavior() { + let bytecode = TestContract::counter().bytecode.to_vec(); + let address = Address::repeat_byte(0xA5); + let mut vm: VmTester = VmTesterBuilder::new() + .with_empty_in_memory_storage() + .with_rich_accounts(1) + .with_bootloader_gas_limit(BATCH_COMPUTATIONAL_GAS_LIMIT) + .with_execution_mode(TxExecutionMode::VerifyExecute) + .with_custom_contracts(vec![ContractToDeploy::new(bytecode, address)]) + .build(); + + let calldata = "7cf5dab00000000000000000000000000000000000000000000000000000000000000006"; + let calldata = hex::decode(calldata).unwrap(); + + let account = &mut vm.rich_accounts[0]; + let tx = account.get_l2_tx_for_execute( + Execute { + contract_address: Some(address), + calldata: calldata.clone(), + value: 0.into(), + factory_deps: vec![], + }, + None, + ); + + vm.vm.push_transaction(tx); + let (res, call_traces) = vm.vm.inspect_with_call_tracer(); + assert!(!res.result.is_failed(), "{:#?}", res.result); + + for call in &call_traces { + check_call(call); + assert_eq!(call.error, None); + assert_eq!(call.revert_reason, None); + } + + let call_to_contract = extract_single_call(&call_traces, |call| call.to == address); + assert_eq!(call_to_contract.from, account.address); + assert_eq!(call_to_contract.input, calldata); +} + +pub(crate) fn test_transfer() { + let mut vm: VmTester = VmTesterBuilder::new() + .with_empty_in_memory_storage() + .with_rich_accounts(1) + .with_bootloader_gas_limit(BATCH_COMPUTATIONAL_GAS_LIMIT) + .with_execution_mode(TxExecutionMode::VerifyExecute) + .build(); + + let recipient = Address::repeat_byte(0x23); + let value = 1_000_000_000.into(); + let account = &mut vm.rich_accounts[0]; + let transfer = account.get_l2_tx_for_execute( + Execute { + contract_address: Some(recipient), + calldata: vec![], + value, + factory_deps: vec![], + }, + None, + ); + + vm.vm.push_transaction(transfer); + let (res, call_traces) = vm.vm.inspect_with_call_tracer(); + assert!(!res.result.is_failed(), "{:#?}", res.result); + + for call in &call_traces { + check_call(call); + assert_eq!(call.error, None); + assert_eq!(call.revert_reason, None); + } + + let transfer_call = extract_single_call(&call_traces, |call| call.to == recipient); + assert_eq!(transfer_call.from, account.address); + assert_eq!(transfer_call.value, value); +} + +pub(crate) fn test_reverted_tx() { + let counter_address = Address::repeat_byte(0x23); + let mut vm: VmTester = VmTesterBuilder::new() + .with_empty_in_memory_storage() + .with_rich_accounts(1) + .with_bootloader_gas_limit(BATCH_COMPUTATIONAL_GAS_LIMIT) + .with_execution_mode(TxExecutionMode::VerifyExecute) + .with_custom_contracts(vec![ContractToDeploy::new( + TestContract::counter().bytecode.to_vec(), + counter_address, + )]) + .build(); + + let account = &mut vm.rich_accounts[0]; + let calldata = TestContract::counter() + .function("incrementWithRevert") + .encode_input(&[Token::Uint(1.into()), Token::Bool(true)]) + .unwrap(); + let reverted_tx = account.get_l2_tx_for_execute( + Execute { + contract_address: Some(counter_address), + calldata, + value: 0.into(), + factory_deps: vec![], + }, + None, + ); + + vm.vm.push_transaction(reverted_tx); + let (res, call_traces) = vm.vm.inspect_with_call_tracer(); + assert_matches!(&res.result, ExecutionResult::Revert { .. }); + + let call_to_contract = extract_single_call(&call_traces, |call| call.to == counter_address); + assert_eq!( + call_to_contract.revert_reason.as_ref().unwrap(), + "This method always reverts" + ); +} + +pub(crate) fn test_out_of_gas() { + let contract_address = Address::repeat_byte(0x23); + let mut vm: VmTester = VmTesterBuilder::new() + .with_empty_in_memory_storage() + .with_rich_accounts(1) + .with_execution_mode(TxExecutionMode::VerifyExecute) + .with_custom_contracts(vec![ContractToDeploy::new( + TestContract::expensive().bytecode.to_vec(), + contract_address, + )]) + .build(); + + let account = &mut vm.rich_accounts[0]; + let execute = Execute { + contract_address: Some(contract_address), + calldata: TestContract::expensive() + .function("expensive") + .encode_input(&[Token::Uint(1_000.into())]) + .unwrap(), + value: 0.into(), + factory_deps: vec![], + }; + let out_of_gas_tx = account.get_l2_tx_for_execute( + execute, + Some(Fee { + gas_limit: 500_000.into(), // insufficient gas + ..Account::default_fee() + }), + ); + + vm.vm.push_transaction(out_of_gas_tx); + let (res, call_traces) = vm.vm.inspect_with_call_tracer(); + assert_matches!(&res.result, ExecutionResult::Revert { .. }); + + let out_of_gas_call = extract_single_call(&call_traces, |call| { + call.from == account.address && call.to == contract_address + }); + assert_eq!(out_of_gas_call.error.as_ref().unwrap(), "Panic"); + assert_eq!(out_of_gas_call.gas_used, out_of_gas_call.gas); + + let parent_call = + extract_single_call(&call_traces, |call| call.calls.contains(out_of_gas_call)); + assert_eq!( + parent_call.revert_reason.as_ref().unwrap(), + "Unknown revert reason" + ); +} + +pub(crate) fn test_reverted_deployment_tx() { + let mut vm: VmTester = VmTesterBuilder::new() + .with_empty_in_memory_storage() + .with_rich_accounts(1) + .with_execution_mode(TxExecutionMode::VerifyExecute) + .build(); + + let account = &mut vm.rich_accounts[0]; + let deploy_tx = account.get_deploy_tx(TestContract::failed_call().bytecode, None, TxType::L2); + + vm.vm.push_transaction(deploy_tx.tx); + let (res, call_traces) = vm.vm.inspect_with_call_tracer(); + assert_matches!(&res.result, ExecutionResult::Success { .. }); + + let constructor_call = extract_single_call(&call_traces, |call| { + call.r#type == CallType::Create && call.from == account.address + }); + assert_eq!(constructor_call.input, [] as [u8; 0]); + assert_eq!(constructor_call.error, None); + assert_eq!(constructor_call.revert_reason, None); + let deploy_address = deployed_address_create(account.address, 0.into()); + assert_eq!(constructor_call.to, deploy_address); + + assert_eq!(constructor_call.calls.len(), 1, "{constructor_call:#?}"); + let inner_call = &constructor_call.calls[0]; + assert_eq!(inner_call.from, deploy_address); + assert_eq!(inner_call.to, MSG_VALUE_SIMULATOR_ADDRESS); + inner_call.revert_reason.as_ref().unwrap(); +} + +pub(crate) fn test_recursive_tx() { + let contract_address = Address::repeat_byte(0x42); + let mut vm: VmTester = VmTesterBuilder::new() + .with_empty_in_memory_storage() + .with_rich_accounts(1) + .with_bootloader_gas_limit(BATCH_COMPUTATIONAL_GAS_LIMIT) + .with_execution_mode(TxExecutionMode::VerifyExecute) + .with_custom_contracts(vec![ContractToDeploy::new( + TestContract::load_test().bytecode.to_vec(), + contract_address, + )]) + .build(); + + let account = &mut vm.rich_accounts[0]; + let calldata = LoadnextContractExecutionParams { + recursive_calls: 20, + ..LoadnextContractExecutionParams::empty() + } + .to_bytes(); + let recursive_tx = account.get_l2_tx_for_execute( + Execute { + contract_address: Some(contract_address), + calldata: calldata.clone(), + value: 0.into(), + factory_deps: vec![], + }, + None, + ); + + vm.vm.push_transaction(recursive_tx); + let (res, call_traces) = vm.vm.inspect_with_call_tracer(); + assert!(!res.result.is_failed(), "{:#?}", res.result); + + let mut call_to_contract = extract_single_call(&call_traces, |call| { + call.to == contract_address && call.input == calldata + }); + let mut depth = 0; + while let Some(child_call) = call_to_contract.calls.first() { + assert_eq!(call_to_contract.calls.len(), 1, "{call_to_contract:#?}"); + assert_eq!(child_call.from, contract_address); + assert_eq!(child_call.to, contract_address); + assert_ne!(child_call.input, call_to_contract.input); + + depth += 1; + call_to_contract = child_call; + } + assert_eq!(depth, 20); +} diff --git a/core/lib/multivm/src/versions/testonly/mod.rs b/core/lib/multivm/src/versions/testonly/mod.rs index 8f24c849272d..c1a603bfeefc 100644 --- a/core/lib/multivm/src/versions/testonly/mod.rs +++ b/core/lib/multivm/src/versions/testonly/mod.rs @@ -20,15 +20,17 @@ use zksync_types::{ get_is_account_key, h256_to_u256, u256_to_h256, utils::storage_key_for_eth_balance, Address, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, U256, }; -use zksync_vm_interface::{ - pubdata::PubdataBuilder, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, -}; pub(super) use self::tester::{ - validation_params, TestedVm, TestedVmForValidation, VmTester, VmTesterBuilder, + validation_params, TestedVm, TestedVmForValidation, TestedVmWithCallTracer, VmTester, + VmTesterBuilder, }; use crate::{ - interface::storage::InMemoryStorage, pubdata_builders::FullPubdataBuilder, + interface::{ + pubdata::PubdataBuilder, storage::InMemoryStorage, L1BatchEnv, L2BlockEnv, SystemEnv, + TxExecutionMode, + }, + pubdata_builders::FullPubdataBuilder, vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT, }; @@ -36,6 +38,7 @@ pub(super) mod account_validation_rules; pub(super) mod block_tip; pub(super) mod bootloader; pub(super) mod bytecode_publishing; +pub(super) mod call_tracer; pub(super) mod circuits; pub(super) mod code_oracle; pub(super) mod default_aa; diff --git a/core/lib/multivm/src/versions/testonly/tester/mod.rs b/core/lib/multivm/src/versions/testonly/tester/mod.rs index c29f2dbbf8f3..a25909525f11 100644 --- a/core/lib/multivm/src/versions/testonly/tester/mod.rs +++ b/core/lib/multivm/src/versions/testonly/tester/mod.rs @@ -8,6 +8,7 @@ use zksync_types::{ writes::StateDiffRecord, Address, L1BatchNumber, StorageKey, Transaction, H256, U256, }; +use zksync_vm_interface::Call; pub(crate) use self::transaction_test_info::{ExpectedError, TransactionTestInfo, TxModifier}; use super::get_empty_storage; @@ -252,3 +253,7 @@ pub(crate) fn validation_params(tx: &L2Tx, system: &SystemEnv) -> ValidationPara timestamp_asserter_params: None, } } + +pub(crate) trait TestedVmWithCallTracer: TestedVm { + fn inspect_with_call_tracer(&mut self) -> (VmExecutionResultAndLogs, Vec); +} diff --git a/core/lib/multivm/src/versions/vm_fast/bootloader_state/l2_block.rs b/core/lib/multivm/src/versions/vm_fast/bootloader_state/l2_block.rs deleted file mode 100644 index 4f05ef30a46d..000000000000 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/l2_block.rs +++ /dev/null @@ -1,78 +0,0 @@ -use std::cmp::Ordering; - -use zksync_types::{web3::keccak256_concat, L2BlockNumber, H256}; - -use super::{snapshot::L2BlockSnapshot, tx::BootloaderTx}; -use crate::{ - interface::{L2Block, L2BlockEnv}, - vm_latest::utils::l2_blocks::l2_block_hash, -}; - -const EMPTY_TXS_ROLLING_HASH: H256 = H256::zero(); - -#[derive(Debug)] -pub(crate) struct BootloaderL2Block { - pub(crate) number: u32, - pub(crate) timestamp: u64, - pub(crate) txs_rolling_hash: H256, // The rolling hash of all the transactions in the miniblock - pub(crate) prev_block_hash: H256, - // Number of the first L2 block tx in L1 batch - pub(crate) first_tx_index: usize, - pub(crate) max_virtual_blocks_to_create: u32, - pub(crate) txs: Vec, -} - -impl BootloaderL2Block { - pub(crate) fn new(l2_block: L2BlockEnv, first_tx_place: usize) -> Self { - Self { - number: l2_block.number, - timestamp: l2_block.timestamp, - txs_rolling_hash: EMPTY_TXS_ROLLING_HASH, - prev_block_hash: l2_block.prev_block_hash, - first_tx_index: first_tx_place, - max_virtual_blocks_to_create: l2_block.max_virtual_blocks_to_create, - txs: vec![], - } - } - - pub(super) fn push_tx(&mut self, tx: BootloaderTx) { - self.update_rolling_hash(tx.hash); - self.txs.push(tx) - } - - pub(crate) fn get_hash(&self) -> H256 { - l2_block_hash( - L2BlockNumber(self.number), - self.timestamp, - self.prev_block_hash, - self.txs_rolling_hash, - ) - } - - fn update_rolling_hash(&mut self, tx_hash: H256) { - self.txs_rolling_hash = keccak256_concat(self.txs_rolling_hash, tx_hash) - } - - pub(crate) fn make_snapshot(&self) -> L2BlockSnapshot { - L2BlockSnapshot { - txs_rolling_hash: self.txs_rolling_hash, - txs_len: self.txs.len(), - } - } - - pub(crate) fn apply_snapshot(&mut self, snapshot: L2BlockSnapshot) { - self.txs_rolling_hash = snapshot.txs_rolling_hash; - match self.txs.len().cmp(&snapshot.txs_len) { - Ordering::Greater => self.txs.truncate(snapshot.txs_len), - Ordering::Less => panic!("Applying snapshot from future is not supported"), - Ordering::Equal => {} - } - } - pub(crate) fn l2_block(&self) -> L2Block { - L2Block { - number: self.number, - timestamp: self.timestamp, - hash: self.get_hash(), - } - } -} diff --git a/core/lib/multivm/src/versions/vm_fast/bootloader_state/mod.rs b/core/lib/multivm/src/versions/vm_fast/bootloader_state/mod.rs deleted file mode 100644 index 73830de2759b..000000000000 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod l2_block; -mod snapshot; -mod state; -mod tx; - -pub(crate) mod utils; -pub(crate) use snapshot::BootloaderStateSnapshot; -pub use state::BootloaderState; diff --git a/core/lib/multivm/src/versions/vm_fast/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_fast/bootloader_state/state.rs deleted file mode 100644 index be4f2881297d..000000000000 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/state.rs +++ /dev/null @@ -1,323 +0,0 @@ -use std::cmp::Ordering; - -use once_cell::sync::OnceCell; -use zksync_types::{vm::VmVersion, L2ChainId, ProtocolVersionId, U256}; - -use super::{ - l2_block::BootloaderL2Block, - tx::BootloaderTx, - utils::{apply_l2_block, apply_pubdata_to_memory, apply_tx_to_memory}, - BootloaderStateSnapshot, -}; -use crate::{ - interface::{ - pubdata::{PubdataBuilder, PubdataInput}, - BootloaderMemory, CompressedBytecodeInfo, L2BlockEnv, TxExecutionMode, - }, - versions::vm_fast::transaction_data::TransactionData, - vm_latest::{ - constants::get_tx_description_offset, utils::l2_blocks::assert_next_block, - MultiVmSubversion, - }, -}; - -/// Intermediate bootloader-related VM state. -/// -/// Required to process transactions one by one (since we intercept the VM execution to execute -/// transactions and add new ones to the memory on the fly). -/// Keeps tracking everything related to the bootloader memory and can restore the whole memory. -/// -/// -/// Serves two purposes: -/// - Tracks where next tx should be pushed to in the bootloader memory. -/// - Tracks which transaction should be executed next. -#[derive(Debug)] -pub struct BootloaderState { - /// ID of the next transaction to be executed. - /// See the structure doc-comment for a better explanation of purpose. - tx_to_execute: usize, - /// Stored txs in bootloader memory - l2_blocks: Vec, - /// The number of 32-byte words spent on the already included compressed bytecodes. - compressed_bytecodes_encoding: usize, - /// Initial memory of bootloader - initial_memory: BootloaderMemory, - /// Mode of txs for execution, it can be changed once per vm lunch - execution_mode: TxExecutionMode, - /// Current offset of the free space in the bootloader memory. - free_tx_offset: usize, - /// Information about the pubdata that will be needed to supply to the L1Messenger - pubdata_information: OnceCell, - /// Protocol version. - protocol_version: ProtocolVersionId, - /// Protocol subversion - subversion: MultiVmSubversion, -} - -impl BootloaderState { - pub(crate) fn new( - execution_mode: TxExecutionMode, - initial_memory: BootloaderMemory, - first_l2_block: L2BlockEnv, - protocol_version: ProtocolVersionId, - ) -> Self { - let l2_block = BootloaderL2Block::new(first_l2_block, 0); - Self { - tx_to_execute: 0, - compressed_bytecodes_encoding: 0, - l2_blocks: vec![l2_block], - initial_memory, - execution_mode, - free_tx_offset: 0, - pubdata_information: Default::default(), - protocol_version, - subversion: MultiVmSubversion::try_from(VmVersion::from(protocol_version)).unwrap(), - } - } - - pub(crate) fn set_refund_for_current_tx(&mut self, refund: u64) { - let current_tx = self.current_tx(); - // We can't set the refund for the latest tx or using the latest l2_block for fining tx - // Because we can fill the whole batch first and then execute txs one by one - let tx = self.find_tx_mut(current_tx); - tx.refund = refund; - } - - pub(crate) fn set_pubdata_input(&mut self, info: PubdataInput) { - self.pubdata_information - .set(info) - .expect("Pubdata information is already set"); - } - - pub(crate) fn start_new_l2_block(&mut self, l2_block: L2BlockEnv) { - let last_block = self.last_l2_block(); - assert!( - !last_block.txs.is_empty(), - "Can not create new miniblocks on top of empty ones" - ); - assert_next_block(&last_block.l2_block(), &l2_block); - self.push_l2_block(l2_block); - } - - /// This method bypass sanity checks and should be used carefully. - pub(crate) fn push_l2_block(&mut self, l2_block: L2BlockEnv) { - self.l2_blocks - .push(BootloaderL2Block::new(l2_block, self.free_tx_index())) - } - - pub(crate) fn push_tx( - &mut self, - tx: TransactionData, - predefined_overhead: u32, - predefined_refund: u64, - compressed_bytecodes: Vec, - trusted_ergs_limit: U256, - chain_id: L2ChainId, - ) -> BootloaderMemory { - let tx_offset = self.free_tx_offset(); - let bootloader_tx = BootloaderTx::new( - tx, - predefined_refund, - predefined_overhead, - trusted_ergs_limit, - compressed_bytecodes, - tx_offset, - chain_id, - ); - - let mut memory = vec![]; - let compressed_bytecode_size = apply_tx_to_memory( - &mut memory, - &bootloader_tx, - self.last_l2_block(), - self.free_tx_index(), - self.free_tx_offset(), - self.compressed_bytecodes_encoding, - self.execution_mode, - self.last_l2_block().txs.is_empty(), - self.subversion, - ); - self.compressed_bytecodes_encoding += compressed_bytecode_size; - self.free_tx_offset = tx_offset + bootloader_tx.encoded_len(); - self.last_mut_l2_block().push_tx(bootloader_tx); - memory - } - - pub(crate) fn last_l2_block(&self) -> &BootloaderL2Block { - self.l2_blocks.last().unwrap() - } - - pub(crate) fn get_pubdata_information(&self) -> &PubdataInput { - self.pubdata_information - .get() - .expect("Pubdata information is not set") - } - - pub(crate) fn settlement_layer_pubdata(&self, pubdata_builder: &dyn PubdataBuilder) -> Vec { - let pubdata_information = self - .pubdata_information - .get() - .expect("Pubdata information is not set"); - pubdata_builder.settlement_layer_pubdata(pubdata_information, self.protocol_version) - } - - fn last_mut_l2_block(&mut self) -> &mut BootloaderL2Block { - self.l2_blocks.last_mut().unwrap() - } - - /// Apply all bootloader transaction to the initial memory - pub(crate) fn bootloader_memory( - &self, - pubdata_builder: &dyn PubdataBuilder, - ) -> BootloaderMemory { - let mut initial_memory = self.initial_memory.clone(); - let mut offset = 0; - let mut compressed_bytecodes_offset = 0; - let mut tx_index = 0; - for l2_block in &self.l2_blocks { - for (num, tx) in l2_block.txs.iter().enumerate() { - let compressed_bytecodes_size = apply_tx_to_memory( - &mut initial_memory, - tx, - l2_block, - tx_index, - offset, - compressed_bytecodes_offset, - self.execution_mode, - num == 0, - self.subversion, - ); - offset += tx.encoded_len(); - compressed_bytecodes_offset += compressed_bytecodes_size; - tx_index += 1; - } - if l2_block.txs.is_empty() { - apply_l2_block(&mut initial_memory, l2_block, tx_index, self.subversion) - } - } - - let pubdata_information = self - .pubdata_information - .get() - .expect("Empty pubdata information"); - - apply_pubdata_to_memory( - &mut initial_memory, - pubdata_builder, - pubdata_information, - self.protocol_version, - self.subversion, - ); - initial_memory - } - - fn free_tx_offset(&self) -> usize { - self.free_tx_offset - } - - pub(crate) fn free_tx_index(&self) -> usize { - let l2_block = self.last_l2_block(); - l2_block.first_tx_index + l2_block.txs.len() - } - - pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> &[CompressedBytecodeInfo] { - if let Some(tx) = self.last_l2_block().txs.last() { - &tx.compressed_bytecodes - } else { - &[] - } - } - - /// Returns the id of current tx - pub(crate) fn current_tx(&self) -> usize { - self.tx_to_execute - .checked_sub(1) - .expect("There are no current tx to execute") - } - - /// Returns the ID of the next transaction to be executed and increments the local transaction counter. - pub(crate) fn move_tx_to_execute_pointer(&mut self) -> usize { - assert!( - self.tx_to_execute < self.free_tx_index(), - "Attempt to execute tx that was not pushed to memory. Tx ID: {}, txs in bootloader: {}", - self.tx_to_execute, - self.free_tx_index() - ); - - let old = self.tx_to_execute; - self.tx_to_execute += 1; - old - } - - /// Get offset of tx description - pub(crate) fn get_tx_description_offset(&self, tx_index: usize) -> usize { - get_tx_description_offset(self.subversion) + self.find_tx(tx_index).offset - } - - pub(crate) fn insert_fictive_l2_block(&mut self) -> &BootloaderL2Block { - let block = self.last_l2_block(); - if !block.txs.is_empty() { - self.start_new_l2_block(L2BlockEnv { - timestamp: block.timestamp + 1, - number: block.number + 1, - prev_block_hash: block.get_hash(), - max_virtual_blocks_to_create: 1, - }); - } - self.last_l2_block() - } - - fn find_tx(&self, tx_index: usize) -> &BootloaderTx { - for block in self.l2_blocks.iter().rev() { - if tx_index >= block.first_tx_index { - return &block.txs[tx_index - block.first_tx_index]; - } - } - panic!("The tx with index {} must exist", tx_index) - } - - fn find_tx_mut(&mut self, tx_index: usize) -> &mut BootloaderTx { - for block in self.l2_blocks.iter_mut().rev() { - if tx_index >= block.first_tx_index { - return &mut block.txs[tx_index - block.first_tx_index]; - } - } - panic!("The tx with index {} must exist", tx_index) - } - - pub(crate) fn get_snapshot(&self) -> BootloaderStateSnapshot { - BootloaderStateSnapshot { - tx_to_execute: self.tx_to_execute, - l2_blocks_len: self.l2_blocks.len(), - last_l2_block: self.last_l2_block().make_snapshot(), - compressed_bytecodes_encoding: self.compressed_bytecodes_encoding, - free_tx_offset: self.free_tx_offset, - is_pubdata_information_provided: self.pubdata_information.get().is_some(), - } - } - - pub(crate) fn apply_snapshot(&mut self, snapshot: BootloaderStateSnapshot) { - self.tx_to_execute = snapshot.tx_to_execute; - self.compressed_bytecodes_encoding = snapshot.compressed_bytecodes_encoding; - self.free_tx_offset = snapshot.free_tx_offset; - match self.l2_blocks.len().cmp(&snapshot.l2_blocks_len) { - Ordering::Greater => self.l2_blocks.truncate(snapshot.l2_blocks_len), - Ordering::Less => panic!("Applying snapshot from future is not supported"), - Ordering::Equal => {} - } - self.last_mut_l2_block() - .apply_snapshot(snapshot.last_l2_block); - - if !snapshot.is_pubdata_information_provided { - self.pubdata_information = Default::default(); - } else { - // Under the correct usage of the snapshots of the bootloader state, - // this assertion should never fail, i.e. since the pubdata information - // can be set only once. However, we have this assertion just in case. - assert!( - self.pubdata_information.get().is_some(), - "Snapshot with no pubdata can not rollback to snapshot with one" - ); - } - } -} diff --git a/core/lib/multivm/src/versions/vm_fast/bootloader_state/tx.rs b/core/lib/multivm/src/versions/vm_fast/bootloader_state/tx.rs deleted file mode 100644 index dc0706561d5e..000000000000 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/tx.rs +++ /dev/null @@ -1,50 +0,0 @@ -use zksync_types::{L2ChainId, H256, U256}; - -use crate::{ - interface::CompressedBytecodeInfo, versions::vm_fast::transaction_data::TransactionData, -}; - -/// Information about tx necessary for execution in bootloader. -#[derive(Debug, Clone)] -pub(crate) struct BootloaderTx { - pub(crate) hash: H256, - /// Encoded transaction - pub(crate) encoded: Vec, - /// Compressed bytecodes, which has been published during this transaction - pub(crate) compressed_bytecodes: Vec, - /// Refunds for this transaction - pub(crate) refund: u64, - /// Gas overhead - pub(crate) gas_overhead: u32, - /// Gas Limit for this transaction. It can be different from the gas limit inside the transaction - pub(crate) trusted_gas_limit: U256, - /// Offset of the tx in bootloader memory - pub(crate) offset: usize, -} - -impl BootloaderTx { - pub(super) fn new( - tx: TransactionData, - predefined_refund: u64, - predefined_overhead: u32, - trusted_gas_limit: U256, - compressed_bytecodes: Vec, - offset: usize, - chain_id: L2ChainId, - ) -> Self { - let hash = tx.tx_hash(chain_id); - Self { - hash, - encoded: tx.into_tokens(), - compressed_bytecodes, - refund: predefined_refund, - gas_overhead: predefined_overhead, - trusted_gas_limit, - offset, - } - } - - pub(super) fn encoded_len(&self) -> usize { - self.encoded.len() - } -} diff --git a/core/lib/multivm/src/versions/vm_fast/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_fast/bootloader_state/utils.rs deleted file mode 100644 index 8883fd33904b..000000000000 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/utils.rs +++ /dev/null @@ -1,236 +0,0 @@ -use zksync_types::{ethabi, h256_to_u256, ProtocolVersionId, U256}; - -use super::{l2_block::BootloaderL2Block, tx::BootloaderTx}; -use crate::{ - interface::{ - pubdata::{PubdataBuilder, PubdataInput}, - BootloaderMemory, CompressedBytecodeInfo, TxExecutionMode, - }, - utils::bytecode, - vm_latest::{ - constants::{ - get_bootloader_tx_description_offset, get_compressed_bytecodes_offset, - get_operator_provided_l1_messenger_pubdata_offset, get_operator_refunds_offset, - get_tx_description_offset, get_tx_operator_l2_block_info_offset, - get_tx_overhead_offset, get_tx_trusted_gas_limit_offset, - BOOTLOADER_TX_DESCRIPTION_SIZE, OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS, - TX_OPERATOR_SLOTS_PER_L2_BLOCK_INFO, - }, - MultiVmSubversion, - }, -}; - -pub(super) fn get_memory_for_compressed_bytecodes( - compressed_bytecodes: &[CompressedBytecodeInfo], -) -> Vec { - let memory_addition: Vec<_> = compressed_bytecodes - .iter() - .flat_map(bytecode::encode_call) - .collect(); - bytecode::bytes_to_be_words(&memory_addition) -} - -#[allow(clippy::too_many_arguments)] -pub(super) fn apply_tx_to_memory( - memory: &mut BootloaderMemory, - bootloader_tx: &BootloaderTx, - bootloader_l2_block: &BootloaderL2Block, - tx_index: usize, - tx_offset: usize, - compressed_bytecodes_size: usize, - execution_mode: TxExecutionMode, - start_new_l2_block: bool, - subversion: MultiVmSubversion, -) -> usize { - let bootloader_description_offset = get_bootloader_tx_description_offset(subversion) - + BOOTLOADER_TX_DESCRIPTION_SIZE * tx_index; - let tx_description_offset = get_tx_description_offset(subversion) + tx_offset; - - memory.push(( - bootloader_description_offset, - assemble_tx_meta(execution_mode, true), - )); - - memory.push(( - bootloader_description_offset + 1, - U256::from_big_endian(&(32 * tx_description_offset).to_be_bytes()), - )); - - let refund_offset = get_operator_refunds_offset(subversion) + tx_index; - memory.push((refund_offset, bootloader_tx.refund.into())); - - let overhead_offset = get_tx_overhead_offset(subversion) + tx_index; - memory.push((overhead_offset, bootloader_tx.gas_overhead.into())); - - let trusted_gas_limit_offset = get_tx_trusted_gas_limit_offset(subversion) + tx_index; - memory.push((trusted_gas_limit_offset, bootloader_tx.trusted_gas_limit)); - - memory.extend( - (tx_description_offset..tx_description_offset + bootloader_tx.encoded_len()) - .zip(bootloader_tx.encoded.clone()), - ); - apply_l2_block_inner( - memory, - bootloader_l2_block, - tx_index, - start_new_l2_block, - subversion, - ); - - // Note, +1 is moving for pointer - let compressed_bytecodes_offset = - get_compressed_bytecodes_offset(subversion) + 1 + compressed_bytecodes_size; - - let encoded_compressed_bytecodes = - get_memory_for_compressed_bytecodes(&bootloader_tx.compressed_bytecodes); - let compressed_bytecodes_encoding = encoded_compressed_bytecodes.len(); - - memory.extend( - (compressed_bytecodes_offset - ..compressed_bytecodes_offset + encoded_compressed_bytecodes.len()) - .zip(encoded_compressed_bytecodes), - ); - compressed_bytecodes_encoding -} - -pub(crate) fn apply_l2_block( - memory: &mut BootloaderMemory, - bootloader_l2_block: &BootloaderL2Block, - txs_index: usize, - subversion: MultiVmSubversion, -) { - apply_l2_block_inner(memory, bootloader_l2_block, txs_index, true, subversion) -} - -fn apply_l2_block_inner( - memory: &mut BootloaderMemory, - bootloader_l2_block: &BootloaderL2Block, - txs_index: usize, - start_new_l2_block: bool, - subversion: MultiVmSubversion, -) { - // Since L2 block information start from the `TX_OPERATOR_L2_BLOCK_INFO_OFFSET` and each - // L2 block info takes `TX_OPERATOR_SLOTS_PER_L2_BLOCK_INFO` slots, the position where the L2 block info - // for this transaction needs to be written is: - - let block_position = get_tx_operator_l2_block_info_offset(subversion) - + txs_index * TX_OPERATOR_SLOTS_PER_L2_BLOCK_INFO; - - memory.extend(vec![ - (block_position, bootloader_l2_block.number.into()), - (block_position + 1, bootloader_l2_block.timestamp.into()), - ( - block_position + 2, - h256_to_u256(bootloader_l2_block.prev_block_hash), - ), - ( - block_position + 3, - if start_new_l2_block { - bootloader_l2_block.max_virtual_blocks_to_create.into() - } else { - U256::zero() - }, - ), - ]) -} - -fn bootloader_memory_input( - pubdata_builder: &dyn PubdataBuilder, - input: &PubdataInput, - protocol_version: ProtocolVersionId, -) -> Vec { - let l2_da_validator_address = pubdata_builder.l2_da_validator(); - let operator_input = pubdata_builder.l1_messenger_operator_input(input, protocol_version); - ethabi::encode(&[ - ethabi::Token::Address(l2_da_validator_address), - ethabi::Token::Bytes(operator_input), - ]) -} - -pub(crate) fn apply_pubdata_to_memory( - memory: &mut BootloaderMemory, - pubdata_builder: &dyn PubdataBuilder, - pubdata_information: &PubdataInput, - protocol_version: ProtocolVersionId, - subversion: MultiVmSubversion, -) { - let (l1_messenger_pubdata_start_slot, pubdata) = match subversion { - MultiVmSubversion::SmallBootloaderMemory | MultiVmSubversion::IncreasedBootloaderMemory => { - // Skipping two slots as they will be filled by the bootloader itself: - // - One slot is for the selector of the call to the L1Messenger. - // - The other slot is for the 0x20 offset for the calldata. - let l1_messenger_pubdata_start_slot = - get_operator_provided_l1_messenger_pubdata_offset(subversion) + 2; - - // Need to skip first word as it represents array offset - // while bootloader expects only [len || data] - let pubdata = ethabi::encode(&[ethabi::Token::Bytes( - pubdata_builder.l1_messenger_operator_input(pubdata_information, protocol_version), - )])[32..] - .to_vec(); - - assert!( - pubdata.len() / 32 <= OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS - 2, - "The encoded pubdata is too big" - ); - - (l1_messenger_pubdata_start_slot, pubdata) - } - MultiVmSubversion::Gateway => { - // Skipping the first slot as it will be filled by the bootloader itself: - // It is for the selector of the call to the L1Messenger. - let l1_messenger_pubdata_start_slot = - get_operator_provided_l1_messenger_pubdata_offset(subversion) + 1; - - let pubdata = - bootloader_memory_input(pubdata_builder, pubdata_information, protocol_version); - - assert!( - // Note that unlike the previous version, the difference is `1`, since now it also includes the offset - pubdata.len() / 32 < OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS, - "The encoded pubdata is too big" - ); - - (l1_messenger_pubdata_start_slot, pubdata) - } - }; - - pubdata - .chunks(32) - .enumerate() - .for_each(|(slot_offset, value)| { - memory.push(( - l1_messenger_pubdata_start_slot + slot_offset, - U256::from(value), - )) - }); -} - -/// Forms a word that contains meta information for the transaction execution. -/// -/// # Current layout -/// -/// - 0 byte (MSB): server-side tx execution mode -/// In the server, we may want to execute different parts of the transaction in the different context -/// For example, when checking validity, we don't want to actually execute transaction and have side effects. -/// -/// Possible values: -/// - 0x00: validate & execute (normal mode) -/// - 0x02: execute but DO NOT validate -/// -/// - 31 byte (LSB): whether to execute transaction or not (at all). -pub(super) fn assemble_tx_meta(execution_mode: TxExecutionMode, execute_tx: bool) -> U256 { - let mut output = [0u8; 32]; - - // Set 0 byte (execution mode) - output[0] = match execution_mode { - TxExecutionMode::VerifyExecute => 0x00, - TxExecutionMode::EstimateFee => 0x00, - TxExecutionMode::EthCall => 0x02, - }; - - // Set 31 byte (marker for tx execution) - output[31] = u8::from(execute_tx); - - U256::from_big_endian(&output) -} diff --git a/core/lib/multivm/src/versions/vm_fast/hook.rs b/core/lib/multivm/src/versions/vm_fast/hook.rs deleted file mode 100644 index b138c6d496d9..000000000000 --- a/core/lib/multivm/src/versions/vm_fast/hook.rs +++ /dev/null @@ -1,39 +0,0 @@ -#[derive(Debug, Copy, Clone)] -pub(crate) enum Hook { - AccountValidationEntered, - PaymasterValidationEntered, - ValidationExited, - ValidationStepEnded, - TxHasEnded, - DebugLog, - DebugReturnData, - NearCallCatch, - AskOperatorForRefund, - NotifyAboutRefund, - PostResult, - FinalBatchInfo, - PubdataRequested, -} - -impl Hook { - /// # Panics - /// Panics if the number does not correspond to any hook. - pub fn from_u32(hook: u32) -> Self { - match hook { - 0 => Hook::AccountValidationEntered, - 1 => Hook::PaymasterValidationEntered, - 2 => Hook::ValidationExited, - 3 => Hook::ValidationStepEnded, - 4 => Hook::TxHasEnded, - 5 => Hook::DebugLog, - 6 => Hook::DebugReturnData, - 7 => Hook::NearCallCatch, - 8 => Hook::AskOperatorForRefund, - 9 => Hook::NotifyAboutRefund, - 10 => Hook::PostResult, - 11 => Hook::FinalBatchInfo, - 12 => Hook::PubdataRequested, - _ => panic!("Unknown hook {}", hook), - } - } -} diff --git a/core/lib/multivm/src/versions/vm_fast/initial_bootloader_memory.rs b/core/lib/multivm/src/versions/vm_fast/initial_bootloader_memory.rs deleted file mode 100644 index 89b22d328ac5..000000000000 --- a/core/lib/multivm/src/versions/vm_fast/initial_bootloader_memory.rs +++ /dev/null @@ -1,43 +0,0 @@ -use zksync_types::{address_to_u256, h256_to_u256, U256}; - -use crate::{interface::L1BatchEnv, vm_latest::utils::fee::get_batch_base_fee}; - -const OPERATOR_ADDRESS_SLOT: usize = 0; -const PREV_BLOCK_HASH_SLOT: usize = 1; -const NEW_BLOCK_TIMESTAMP_SLOT: usize = 2; -const NEW_BLOCK_NUMBER_SLOT: usize = 3; -const FAIR_PUBDATA_PRICE_SLOT: usize = 4; -const FAIR_L2_GAS_PRICE_SLOT: usize = 5; -const EXPECTED_BASE_FEE_SLOT: usize = 6; -const SHOULD_SET_NEW_BLOCK_SLOT: usize = 7; - -/// Returns the initial memory for the bootloader based on the current batch environment. -pub(crate) fn bootloader_initial_memory(l1_batch: &L1BatchEnv) -> Vec<(usize, U256)> { - let (prev_block_hash, should_set_new_block) = l1_batch - .previous_batch_hash - .map(|prev_block_hash| (h256_to_u256(prev_block_hash), U256::one())) - .unwrap_or_default(); - - vec![ - ( - OPERATOR_ADDRESS_SLOT, - address_to_u256(&l1_batch.fee_account), - ), - (PREV_BLOCK_HASH_SLOT, prev_block_hash), - (NEW_BLOCK_TIMESTAMP_SLOT, U256::from(l1_batch.timestamp)), - (NEW_BLOCK_NUMBER_SLOT, U256::from(l1_batch.number.0)), - ( - FAIR_PUBDATA_PRICE_SLOT, - U256::from(l1_batch.fee_input.fair_pubdata_price()), - ), - ( - FAIR_L2_GAS_PRICE_SLOT, - U256::from(l1_batch.fee_input.fair_l2_gas_price()), - ), - ( - EXPECTED_BASE_FEE_SLOT, - U256::from(get_batch_base_fee(l1_batch)), - ), - (SHOULD_SET_NEW_BLOCK_SLOT, should_set_new_block), - ] -} diff --git a/core/lib/multivm/src/versions/vm_fast/mod.rs b/core/lib/multivm/src/versions/vm_fast/mod.rs index dca575138553..291961d3312a 100644 --- a/core/lib/multivm/src/versions/vm_fast/mod.rs +++ b/core/lib/multivm/src/versions/vm_fast/mod.rs @@ -2,21 +2,16 @@ pub use zksync_vm2::interface; pub(crate) use self::version::FastVmVersion; pub use self::{ - tracers::{FullValidationTracer, ValidationTracer}, + tracers::{CallTracer, FullValidationTracer, ValidationTracer}, vm::Vm, }; -mod bootloader_state; mod bytecode; mod events; mod glue; -mod hook; -mod initial_bootloader_memory; -mod refund; #[cfg(test)] mod tests; mod tracers; -mod transaction_data; mod utils; mod version; mod vm; diff --git a/core/lib/multivm/src/versions/vm_fast/tests/call_tracer.rs b/core/lib/multivm/src/versions/vm_fast/tests/call_tracer.rs new file mode 100644 index 000000000000..9a990bb8d200 --- /dev/null +++ b/core/lib/multivm/src/versions/vm_fast/tests/call_tracer.rs @@ -0,0 +1,31 @@ +use crate::versions::{testonly::call_tracer, vm_fast::Vm}; + +#[test] +fn basic_behavior() { + call_tracer::test_basic_behavior::>(); +} + +#[test] +fn transfer() { + call_tracer::test_transfer::>(); +} + +#[test] +fn reverted_tx() { + call_tracer::test_reverted_tx::>(); +} + +#[test] +fn reverted_deployment() { + call_tracer::test_reverted_deployment_tx::>(); +} + +#[test] +fn out_of_gas() { + call_tracer::test_out_of_gas::>(); +} + +#[test] +fn recursive_tx() { + call_tracer::test_recursive_tx::>(); +} diff --git a/core/lib/multivm/src/versions/vm_fast/tests/mod.rs b/core/lib/multivm/src/versions/vm_fast/tests/mod.rs index e148444922ba..89edd85b86f1 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/mod.rs @@ -8,21 +8,24 @@ use zksync_vm_interface::{ pubdata::{PubdataBuilder, PubdataInput}, storage::ReadStorage, tracer::ViolatedValidationRule, - CurrentExecutionState, InspectExecutionMode, L2BlockEnv, VmExecutionMode, + Call, CurrentExecutionState, InspectExecutionMode, L2BlockEnv, VmExecutionMode, VmExecutionResultAndLogs, VmInterface, }; use super::{FullValidationTracer, ValidationTracer, Vm}; use crate::{ interface::storage::{ImmutableStorageView, InMemoryStorage}, - versions::testonly::{validation_params, TestedVm, TestedVmForValidation}, - vm_fast::tracers::WithBuiltinTracers, + versions::testonly::{ + validation_params, TestedVm, TestedVmForValidation, TestedVmWithCallTracer, + }, + vm_fast::{tracers::WithBuiltinTracers, CallTracer}, }; mod account_validation_rules; mod block_tip; mod bootloader; mod bytecode_publishing; +mod call_tracer; mod circuits; mod code_oracle; mod default_aa; @@ -180,7 +183,7 @@ where } } -impl TestedVmForValidation for Vm, (), FullValidationTracer> { +impl TestedVmForValidation for TestedFastVm<(), FullValidationTracer> { fn run_validation(&mut self, tx: L2Tx, timestamp: u64) -> Option { let validation_params = validation_params(&tx, &self.system_env); self.push_transaction(tx.into()); @@ -189,3 +192,11 @@ impl TestedVmForValidation for Vm, (), Ful tracer.1.validation_error() } } + +impl TestedVmWithCallTracer for TestedFastVm { + fn inspect_with_call_tracer(&mut self) -> (VmExecutionResultAndLogs, Vec) { + let mut tracer = (CallTracer::default(), ()); + let result = self.inspect(&mut tracer, InspectExecutionMode::OneTx); + (result, tracer.0.into_result()) + } +} diff --git a/core/lib/multivm/src/versions/vm_fast/tracers/calls.rs b/core/lib/multivm/src/versions/vm_fast/tracers/calls.rs new file mode 100644 index 000000000000..2413e5916a25 --- /dev/null +++ b/core/lib/multivm/src/versions/vm_fast/tracers/calls.rs @@ -0,0 +1,159 @@ +use zksync_system_constants::CONTRACT_DEPLOYER_ADDRESS; +use zksync_types::{zk_evm_types::FarCallOpcode, U256}; +use zksync_vm2::{ + interface::{ + CallframeInterface, CallingMode, Opcode, OpcodeType, ReturnType, ShouldStop, + StateInterface, Tracer, + }, + FatPointer, +}; + +use crate::{ + interface::{Call, CallType, VmRevertReason}, + vm_fast::utils::read_raw_fat_pointer, +}; + +/// Call tracer for the fast VM. +#[derive(Debug, Clone, Default)] +pub struct CallTracer { + stack: Vec, + finished_calls: Vec, + current_stack_depth: usize, + // TODO: report as metrics + max_stack_depth: usize, + max_near_calls: usize, +} + +#[derive(Debug, Clone)] +struct FarcallAndNearCallCount { + farcall: Call, + near_calls_after: usize, +} + +impl CallTracer { + /// Converts this tracer into the captured calls. + pub fn into_result(self) -> Vec { + self.finished_calls + } +} + +impl Tracer for CallTracer { + fn after_instruction( + &mut self, + state: &mut S, + ) -> ShouldStop { + match OP::VALUE { + Opcode::FarCall(ty) => { + self.current_stack_depth += 1; + self.max_stack_depth = self.max_stack_depth.max(self.current_stack_depth); + + let current_gas = state.current_frame().gas() as u64; + let from = state.current_frame().caller(); + let to = state.current_frame().address(); + let input = if current_gas == 0 { + vec![] + } else { + read_raw_fat_pointer(state, state.read_register(1).0) + }; + let value = U256::from(state.current_frame().context_u128()); + let ty = match ty { + CallingMode::Normal => CallType::Call(FarCallOpcode::Normal), + CallingMode::Delegate => CallType::Call(FarCallOpcode::Delegate), + CallingMode::Mimic => { + let prev_this_address = state.callframe(1).address(); + if prev_this_address == CONTRACT_DEPLOYER_ADDRESS { + // EraVM contract creation is encoded as a mimic call from `ContractDeployer` to the created contract. + CallType::Create + } else { + CallType::Call(FarCallOpcode::Mimic) + } + } + }; + + self.stack.push(FarcallAndNearCallCount { + farcall: Call { + r#type: ty, + from, + to, + // The previous frame always exists directly after a far call + parent_gas: current_gas + state.callframe(1).gas() as u64, + gas: current_gas, + input, + value, + ..Default::default() + }, + near_calls_after: 0, + }); + } + Opcode::NearCall => { + self.current_stack_depth += 1; + self.max_stack_depth = self.max_stack_depth.max(self.current_stack_depth); + + if let Some(frame) = self.stack.last_mut() { + frame.near_calls_after += 1; + self.max_near_calls = self.max_near_calls.max(frame.near_calls_after); + } + } + Opcode::Ret(variant) => { + self.current_stack_depth -= 1; + + let Some(mut current_call) = self.stack.pop() else { + return ShouldStop::Continue; + }; + + if current_call.near_calls_after == 0 { + // Might overflow due to stipend + current_call.farcall.gas_used = current_call + .farcall + .parent_gas + .saturating_sub(state.current_frame().gas() as u64); + + let (maybe_output_ptr, is_pointer) = state.read_register(1); + let output = if is_pointer { + let output_ptr = FatPointer::from(maybe_output_ptr); + if output_ptr.length == 0 && output_ptr.offset == 0 { + // Trivial pointer, which is formally cannot be dereferenced. This only matters + // when extracting the revert reason; the legacy VM treats the trivial pointer specially. + None + } else { + Some(read_raw_fat_pointer(state, maybe_output_ptr)) + } + } else { + None + }; + + match variant { + ReturnType::Normal => { + current_call.farcall.output = output.unwrap_or_default(); + } + ReturnType::Revert => { + current_call.farcall.revert_reason = + Some(if let Some(output) = &output { + VmRevertReason::from(output.as_slice()).to_string() + } else { + "Unknown revert reason".to_owned() + }); + } + ReturnType::Panic => { + current_call.farcall.error = Some("Panic".to_string()); + } + } + + // If there is a parent call, push the current call to it + // Otherwise, put the current call back on the stack, because it's the top level call + if let Some(parent_call) = self.stack.last_mut() { + parent_call.farcall.calls.push(current_call.farcall); + } else { + self.finished_calls.push(current_call.farcall); + } + } else { + current_call.near_calls_after -= 1; + self.stack.push(current_call); + } + } + _ => {} + } + + ShouldStop::Continue + } +} diff --git a/core/lib/multivm/src/versions/vm_fast/tracers/evm_deploy.rs b/core/lib/multivm/src/versions/vm_fast/tracers/evm_deploy.rs index 1202b5b94dd2..deb06366eb36 100644 --- a/core/lib/multivm/src/versions/vm_fast/tracers/evm_deploy.rs +++ b/core/lib/multivm/src/versions/vm_fast/tracers/evm_deploy.rs @@ -8,7 +8,7 @@ use zksync_vm2::interface::{ CallframeInterface, CallingMode, GlobalStateInterface, Opcode, OpcodeType, ShouldStop, Tracer, }; -use crate::vm_fast::utils::read_fat_pointer; +use crate::vm_fast::utils::read_raw_fat_pointer; /// Container for dynamic bytecodes added by [`EvmDeployTracer`]. #[derive(Debug, Clone, Default)] @@ -54,7 +54,7 @@ impl EvmDeployTracer { return; } - let data = read_fat_pointer(state, state.read_register(1).0); + let data = read_raw_fat_pointer(state, state.read_register(1).0); if data.len() < 4 { return; } diff --git a/core/lib/multivm/src/versions/vm_fast/tracers/mod.rs b/core/lib/multivm/src/versions/vm_fast/tracers/mod.rs index 3d9602536743..db527bdbaceb 100644 --- a/core/lib/multivm/src/versions/vm_fast/tracers/mod.rs +++ b/core/lib/multivm/src/versions/vm_fast/tracers/mod.rs @@ -3,10 +3,14 @@ use zksync_vm2::interface::{CycleStats, GlobalStateInterface, OpcodeType, ShouldStop, Tracer}; pub(super) use self::evm_deploy::DynamicBytecodes; -pub use self::validation::{FullValidationTracer, ValidationTracer}; +pub use self::{ + calls::CallTracer, + validation::{FullValidationTracer, ValidationTracer}, +}; use self::{circuits::CircuitsTracer, evm_deploy::EvmDeployTracer}; use crate::interface::CircuitStatistic; +mod calls; mod circuits; mod evm_deploy; mod validation; diff --git a/core/lib/multivm/src/versions/vm_fast/tracers/validation.rs b/core/lib/multivm/src/versions/vm_fast/tracers/validation.rs index 52b0a4747b7d..6833051c5407 100644 --- a/core/lib/multivm/src/versions/vm_fast/tracers/validation.rs +++ b/core/lib/multivm/src/versions/vm_fast/tracers/validation.rs @@ -14,7 +14,7 @@ use zksync_vm_interface::tracer::{ TimestampAsserterParams, ValidationParams, ValidationTraces, ViolatedValidationRule, }; -use crate::{tracers::TIMESTAMP_ASSERTER_FUNCTION_SELECTOR, vm_fast::utils::read_fat_pointer}; +use crate::{tracers::TIMESTAMP_ASSERTER_FUNCTION_SELECTOR, vm_fast::utils::read_raw_fat_pointer}; /// [`Tracer`] used for account validation per [EIP-4337] and [EIP-7562]. /// @@ -157,7 +157,7 @@ impl Tracer for FullValidationTracer { // Intercept calls to keccak, whitelist storage slots corresponding to the hash let code_address = state.current_frame().code_address(); if code_address == KECCAK256_PRECOMPILE_ADDRESS { - let calldata = read_fat_pointer(state, state.read_register(1).0); + let calldata = read_raw_fat_pointer(state, state.read_register(1).0); if calldata.len() != 64 { return ShouldStop::Continue; } @@ -185,7 +185,7 @@ impl Tracer for FullValidationTracer { if let Some(ref params) = self.timestamp_asserter_params { if code_address == params.address { - let calldata = read_fat_pointer(state, state.read_register(1).0); + let calldata = read_raw_fat_pointer(state, state.read_register(1).0); if calldata.len() == 68 && calldata[..4] == TIMESTAMP_ASSERTER_FUNCTION_SELECTOR { @@ -215,7 +215,7 @@ impl Tracer for FullValidationTracer { } Ret(kind) => { if self.add_return_value_to_allowed_slots && kind == Normal { - let return_value = read_fat_pointer(state, state.read_register(1).0); + let return_value = read_raw_fat_pointer(state, state.read_register(1).0); self.slots_obtained_via_keccak .insert(return_value.as_slice().into()); } diff --git a/core/lib/multivm/src/versions/vm_fast/transaction_data.rs b/core/lib/multivm/src/versions/vm_fast/transaction_data.rs deleted file mode 100644 index 02697beee341..000000000000 --- a/core/lib/multivm/src/versions/vm_fast/transaction_data.rs +++ /dev/null @@ -1,340 +0,0 @@ -use std::convert::TryInto; - -use zksync_types::{ - address_to_h256, - bytecode::BytecodeHash, - ethabi::{encode, Address, Token}, - fee::{encoding_len, Fee}, - h256_to_u256, - l1::is_l1_tx_type, - l2::{L2Tx, TransactionType}, - transaction_request::{PaymasterParams, TransactionRequest}, - web3::Bytes, - Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, -}; - -use crate::{ - utils::bytecode::bytes_to_be_words, - vm_latest::{ - constants::{MAX_GAS_PER_PUBDATA_BYTE, TX_MAX_COMPUTE_GAS_LIMIT}, - utils::overhead::derive_overhead, - }, -}; - -/// This structure represents the data that is used by -/// the Bootloader to describe the transaction. -#[derive(Debug, Default, Clone)] -pub(crate) struct TransactionData { - pub(crate) tx_type: u8, - pub(crate) from: Address, - pub(crate) to: Option
, - pub(crate) gas_limit: U256, - pub(crate) pubdata_price_limit: U256, - pub(crate) max_fee_per_gas: U256, - pub(crate) max_priority_fee_per_gas: U256, - pub(crate) paymaster: Address, - pub(crate) nonce: U256, - pub(crate) value: U256, - // The reserved fields that are unique for different types of transactions. - // E.g. nonce is currently used in all transaction, but it should not be mandatory - // in the long run. - pub(crate) reserved: [U256; 4], - pub(crate) data: Vec, - pub(crate) signature: Vec, - // The factory deps provided with the transaction. - // Note that *only hashes* of these bytecodes are signed by the user - // and they are used in the ABI encoding of the struct. - // TODO: include this into the tx signature as part of SMA-1010 - pub(crate) factory_deps: Vec>, - pub(crate) paymaster_input: Vec, - pub(crate) reserved_dynamic: Vec, - pub(crate) raw_bytes: Option>, -} - -impl From for TransactionData { - fn from(execute_tx: Transaction) -> Self { - match execute_tx.common_data { - ExecuteTransactionCommon::L2(common_data) => { - let nonce = U256::from_big_endian(&common_data.nonce.to_be_bytes()); - - let should_check_chain_id = if matches!( - common_data.transaction_type, - TransactionType::LegacyTransaction - ) && common_data.extract_chain_id().is_some() - { - U256([1, 0, 0, 0]) - } else { - U256::zero() - }; - - // Ethereum transactions do not sign gas per pubdata limit, and so for them we need to use - // some default value. We use the maximum possible value that is allowed by the bootloader - // (i.e. we can not use u64::MAX, because the bootloader requires gas per pubdata for such - // transactions to be higher than `MAX_GAS_PER_PUBDATA_BYTE`). - let gas_per_pubdata_limit = if common_data.transaction_type.is_ethereum_type() { - MAX_GAS_PER_PUBDATA_BYTE.into() - } else { - common_data.fee.gas_per_pubdata_limit - }; - - TransactionData { - tx_type: (common_data.transaction_type as u32) as u8, - from: common_data.initiator_address, - to: execute_tx.execute.contract_address, - gas_limit: common_data.fee.gas_limit, - pubdata_price_limit: gas_per_pubdata_limit, - max_fee_per_gas: common_data.fee.max_fee_per_gas, - max_priority_fee_per_gas: common_data.fee.max_priority_fee_per_gas, - paymaster: common_data.paymaster_params.paymaster, - nonce, - value: execute_tx.execute.value, - reserved: [ - should_check_chain_id, - U256::zero(), - U256::zero(), - U256::zero(), - ], - data: execute_tx.execute.calldata, - signature: common_data.signature, - factory_deps: execute_tx.execute.factory_deps, - paymaster_input: common_data.paymaster_params.paymaster_input, - reserved_dynamic: vec![], - raw_bytes: execute_tx.raw_bytes.map(|a| a.0), - } - } - ExecuteTransactionCommon::L1(common_data) => { - let refund_recipient = h256_to_u256(address_to_h256(&common_data.refund_recipient)); - TransactionData { - tx_type: common_data.tx_format() as u8, - from: common_data.sender, - to: execute_tx.execute.contract_address, - gas_limit: common_data.gas_limit, - pubdata_price_limit: common_data.gas_per_pubdata_limit, - // It doesn't matter what we put here, since - // the bootloader does not charge anything - max_fee_per_gas: common_data.max_fee_per_gas, - max_priority_fee_per_gas: U256::zero(), - paymaster: Address::default(), - nonce: U256::from(common_data.serial_id.0), // priority op ID - value: execute_tx.execute.value, - reserved: [ - common_data.to_mint, - refund_recipient, - U256::zero(), - U256::zero(), - ], - data: execute_tx.execute.calldata, - // The signature isn't checked for L1 transactions so we don't care - signature: vec![], - factory_deps: execute_tx.execute.factory_deps, - paymaster_input: vec![], - reserved_dynamic: vec![], - raw_bytes: None, - } - } - ExecuteTransactionCommon::ProtocolUpgrade(common_data) => { - let refund_recipient = h256_to_u256(address_to_h256(&common_data.refund_recipient)); - TransactionData { - tx_type: common_data.tx_format() as u8, - from: common_data.sender, - to: execute_tx.execute.contract_address, - gas_limit: common_data.gas_limit, - pubdata_price_limit: common_data.gas_per_pubdata_limit, - // It doesn't matter what we put here, since - // the bootloader does not charge anything - max_fee_per_gas: common_data.max_fee_per_gas, - max_priority_fee_per_gas: U256::zero(), - paymaster: Address::default(), - nonce: U256::from(common_data.upgrade_id as u16), - value: execute_tx.execute.value, - reserved: [ - common_data.to_mint, - refund_recipient, - U256::zero(), - U256::zero(), - ], - data: execute_tx.execute.calldata, - // The signature isn't checked for L1 transactions so we don't care - signature: vec![], - factory_deps: execute_tx.execute.factory_deps, - paymaster_input: vec![], - reserved_dynamic: vec![], - raw_bytes: None, - } - } - } - } -} - -impl TransactionData { - pub(crate) fn abi_encode_with_custom_factory_deps( - self, - factory_deps_hashes: Vec, - ) -> Vec { - encode(&[Token::Tuple(vec![ - Token::Uint(U256::from_big_endian(&self.tx_type.to_be_bytes())), - Token::Address(self.from), - Token::Address(self.to.unwrap_or_default()), - Token::Uint(self.gas_limit), - Token::Uint(self.pubdata_price_limit), - Token::Uint(self.max_fee_per_gas), - Token::Uint(self.max_priority_fee_per_gas), - Token::Address(self.paymaster), - Token::Uint(self.nonce), - Token::Uint(self.value), - Token::FixedArray(self.reserved.iter().copied().map(Token::Uint).collect()), - Token::Bytes(self.data), - Token::Bytes(self.signature), - Token::Array(factory_deps_hashes.into_iter().map(Token::Uint).collect()), - Token::Bytes(self.paymaster_input), - Token::Bytes(self.reserved_dynamic), - ])]) - } - - pub(crate) fn abi_encode(self) -> Vec { - let factory_deps_hashes = self - .factory_deps - .iter() - .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) - .collect(); - self.abi_encode_with_custom_factory_deps(factory_deps_hashes) - } - - pub(crate) fn into_tokens(self) -> Vec { - bytes_to_be_words(&self.abi_encode()) - } - - pub(crate) fn overhead_gas(&self) -> u32 { - let encoded_len = encoding_len( - self.data.len() as u64, - self.signature.len() as u64, - self.factory_deps.len() as u64, - self.paymaster_input.len() as u64, - self.reserved_dynamic.len() as u64, - ); - - derive_overhead(encoded_len) - } - - pub(crate) fn trusted_ergs_limit(&self) -> U256 { - // No transaction is allowed to spend more than `TX_MAX_COMPUTE_GAS_LIMIT` gas on compute. - U256::from(TX_MAX_COMPUTE_GAS_LIMIT).min(self.gas_limit) - } - - pub(crate) fn tx_hash(&self, chain_id: L2ChainId) -> H256 { - if is_l1_tx_type(self.tx_type) { - return self.canonical_l1_tx_hash().unwrap(); - } - - let l2_tx: L2Tx = self.clone().try_into().unwrap(); - let mut transaction_request: TransactionRequest = l2_tx.into(); - transaction_request.chain_id = Some(chain_id.as_u64()); - - // It is assumed that the `TransactionData` always has all the necessary components to recover the hash. - transaction_request - .get_tx_hash() - .expect("Could not recover L2 transaction hash") - } - - fn canonical_l1_tx_hash(&self) -> Result { - use zksync_types::web3::keccak256; - - if !is_l1_tx_type(self.tx_type) { - return Err(TxHashCalculationError::CannotCalculateL1HashForL2Tx); - } - - let encoded_bytes = self.clone().abi_encode(); - - Ok(H256(keccak256(&encoded_bytes))) - } -} - -#[derive(Debug, Clone, Copy)] -pub(crate) enum TxHashCalculationError { - CannotCalculateL1HashForL2Tx, - CannotCalculateL2HashForL1Tx, -} - -impl TryInto for TransactionData { - type Error = TxHashCalculationError; - - fn try_into(self) -> Result { - if is_l1_tx_type(self.tx_type) { - return Err(TxHashCalculationError::CannotCalculateL2HashForL1Tx); - } - - let common_data = L2TxCommonData { - transaction_type: (self.tx_type as u32).try_into().unwrap(), - nonce: Nonce(self.nonce.as_u32()), - fee: Fee { - max_fee_per_gas: self.max_fee_per_gas, - max_priority_fee_per_gas: self.max_priority_fee_per_gas, - gas_limit: self.gas_limit, - gas_per_pubdata_limit: self.pubdata_price_limit, - }, - signature: self.signature, - input: None, - initiator_address: self.from, - paymaster_params: PaymasterParams { - paymaster: self.paymaster, - paymaster_input: self.paymaster_input, - }, - }; - let execute = Execute { - contract_address: self.to, - value: self.value, - calldata: self.data, - factory_deps: self.factory_deps, - }; - - Ok(L2Tx { - execute, - common_data, - received_timestamp_ms: 0, - raw_bytes: self.raw_bytes.map(Bytes::from), - }) - } -} - -#[cfg(test)] -mod tests { - use zksync_types::fee::encoding_len; - - use super::*; - - #[test] - fn test_consistency_with_encoding_length() { - let transaction = TransactionData { - tx_type: 113, - from: Address::random(), - to: Some(Address::random()), - gas_limit: U256::from(1u32), - pubdata_price_limit: U256::from(1u32), - max_fee_per_gas: U256::from(1u32), - max_priority_fee_per_gas: U256::from(1u32), - paymaster: Address::random(), - nonce: U256::zero(), - value: U256::zero(), - // The reserved fields that are unique for different types of transactions. - // E.g. nonce is currently used in all transaction, but it should not be mandatory - // in the long run. - reserved: [U256::zero(); 4], - data: vec![0u8; 65], - signature: vec![0u8; 75], - // The factory deps provided with the transaction. - // Note that *only hashes* of these bytecodes are signed by the user - // and they are used in the ABI encoding of the struct. - // TODO: include this into the tx signature as part of SMA-1010 - factory_deps: vec![vec![0u8; 32], vec![1u8; 32]], - paymaster_input: vec![0u8; 85], - reserved_dynamic: vec![0u8; 32], - raw_bytes: None, - }; - - let assumed_encoded_len = encoding_len(65, 75, 2, 85, 32); - - let true_encoding_len = transaction.into_tokens().len(); - - assert_eq!(assumed_encoded_len, true_encoding_len); - } -} diff --git a/core/lib/multivm/src/versions/vm_fast/utils.rs b/core/lib/multivm/src/versions/vm_fast/utils.rs index 20a6545d3385..8b3f57be988d 100644 --- a/core/lib/multivm/src/versions/vm_fast/utils.rs +++ b/core/lib/multivm/src/versions/vm_fast/utils.rs @@ -1,8 +1,11 @@ use zksync_types::U256; use zksync_vm2::{interface::StateInterface, FatPointer}; -pub(super) fn read_fat_pointer(state: &S, raw: U256) -> Vec { - let pointer = FatPointer::from(raw); +pub(super) fn read_raw_fat_pointer(state: &S, raw: U256) -> Vec { + read_fat_pointer(state, FatPointer::from(raw)) +} + +pub(super) fn read_fat_pointer(state: &S, pointer: FatPointer) -> Vec { let length = pointer.length - pointer.offset; let start = pointer.start + pointer.offset; let mut result = vec![0; length as usize]; diff --git a/core/lib/multivm/src/versions/vm_fast/vm.rs b/core/lib/multivm/src/versions/vm_fast/vm.rs index 6b14409a2e08..5065b8a7c67d 100644 --- a/core/lib/multivm/src/versions/vm_fast/vm.rs +++ b/core/lib/multivm/src/versions/vm_fast/vm.rs @@ -25,12 +25,8 @@ use zksync_vm2::{ }; use super::{ - bootloader_state::{BootloaderState, BootloaderStateSnapshot}, bytecode::compress_bytecodes, - hook::Hook, - initial_bootloader_memory::bootloader_initial_memory, tracers::{DynamicBytecodes, ValidationTracer, WithBuiltinTracers}, - transaction_data::TransactionData, }; use crate::{ glue::GlueInto, @@ -44,16 +40,19 @@ use crate::{ VmInterfaceHistoryEnabled, VmRevertReason, VmTrackingContracts, }, utils::events::extract_l2tol1logs_from_l1_messenger, - vm_fast::{ - bootloader_state::utils::{apply_l2_block, apply_pubdata_to_memory}, - events::merge_events, - refund::compute_refund, - version::FastVmVersion, - }, - vm_latest::constants::{ - get_operator_refunds_offset, get_result_success_first_slot, - get_vm_hook_params_start_position, get_vm_hook_position, TX_GAS_LIMIT_OFFSET, - VM_HOOK_PARAMS_COUNT, + vm_fast::{events::merge_events, version::FastVmVersion}, + vm_latest::{ + bootloader::{ + utils::{apply_l2_block, apply_pubdata_to_memory}, + BootloaderState, BootloaderStateSnapshot, + }, + constants::{ + get_operator_refunds_offset, get_result_success_first_slot, + get_vm_hook_params_start_position, get_vm_hook_position, TX_GAS_LIMIT_OFFSET, + VM_HOOK_PARAMS_COUNT, + }, + utils::refund::compute_refund, + TransactionData, VmHook, }, VmVersion, }; @@ -136,7 +135,7 @@ impl Vm { &system_env.base_system_smart_contracts.bootloader, true, ); - let bootloader_memory = bootloader_initial_memory(&batch_env); + let bootloader_memory = BootloaderState::initial_memory(&batch_env); let mut inner = VirtualMachine::new( BOOTLOADER_ADDRESS, @@ -258,11 +257,11 @@ impl Vm { pub(crate) fn push_transaction_inner( &mut self, - tx: zksync_types::Transaction, + tx: Transaction, refund: u64, with_compression: bool, ) { - let tx: TransactionData = tx.into(); + let tx = TransactionData::new(tx, false); let overhead = tx.overhead_gas(); self.insert_bytecodes(tx.factory_deps.iter().map(|dep| &dep[..])); @@ -432,9 +431,9 @@ where } }; - let hook = Hook::from_u32(hook); + let hook = VmHook::new(hook); match hook { - Hook::AccountValidationEntered => { + VmHook::AccountValidationEntered => { assert!( account_validation_gas_split.is_none(), "Account validation can't be nested" @@ -453,7 +452,7 @@ where self.inner.current_frame().set_gas(gas_given); } - Hook::ValidationExited => { + VmHook::ValidationExited => { tracer.validation.validation_exited(); if let Some(AccountValidationGasSplit { @@ -467,13 +466,13 @@ where } } - Hook::ValidationStepEnded => { + VmHook::ValidationStepEnded => { if Val::STOP_AFTER_VALIDATION { break (ExecutionResult::Success { output: vec![] }, true); } } - Hook::TxHasEnded => { + VmHook::TxHasEnded => { if let VmExecutionMode::OneTx = execution_mode { // The bootloader may invoke `TxHasEnded` hook without posting a tx result previously. One case when this can happen // is estimating gas for L1 transactions, if a transaction runs out of gas during execution. @@ -493,7 +492,7 @@ where break (tx_result, false); } } - Hook::AskOperatorForRefund => { + VmHook::AskOperatorForRefund => { if track_refunds { let [bootloader_refund, gas_spent_on_pubdata, gas_per_pubdata_byte] = self.get_hook_params(); @@ -535,12 +534,12 @@ where .set_refund_for_current_tx(refund_value); } } - Hook::NotifyAboutRefund => { + VmHook::NotifyAboutRefund => { if track_refunds { refunds.gas_refunded = self.get_hook_params()[0].low_u64() } } - Hook::PostResult => { + VmHook::PostResult => { let result = self.get_hook_params()[0]; let value = self.get_hook_params()[1]; let fp = FatPointer::from(value); @@ -556,7 +555,7 @@ where } }); } - Hook::FinalBatchInfo => { + VmHook::FinalBatchInfo => { // set fictive l2 block let txs_index = self.bootloader_state.free_tx_index(); let l2_block = self.bootloader_state.insert_fictive_l2_block(); @@ -564,7 +563,7 @@ where apply_l2_block(&mut memory, l2_block, txs_index, self.vm_version.into()); self.write_to_bootloader_heap(memory); } - Hook::PubdataRequested => { + VmHook::PubdataRequested => { if !matches!(execution_mode, VmExecutionMode::Batch) { unreachable!("We do not provide the pubdata when executing the block tip or a single transaction"); } @@ -614,14 +613,14 @@ where self.write_to_bootloader_heap(memory_to_apply); } - Hook::PaymasterValidationEntered => { /* unused */ } - Hook::DebugLog => { + VmHook::PaymasterValidationEntered => { /* unused */ } + VmHook::DebugLog => { let (log, log_arg) = self.get_debug_log(); let last_tx = self.bootloader_state.last_l2_block().txs.last(); let tx_hash = last_tx.map(|tx| tx.hash); tracing::trace!(tx = ?tx_hash, "{log}: {log_arg}"); } - Hook::DebugReturnData | Hook::NearCallCatch => { + VmHook::DebugReturnData | VmHook::NearCallCatch => { // These hooks are for debug purposes only } } diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader/init.rs b/core/lib/multivm/src/versions/vm_latest/bootloader/init.rs new file mode 100644 index 000000000000..7897ada6ad23 --- /dev/null +++ b/core/lib/multivm/src/versions/vm_latest/bootloader/init.rs @@ -0,0 +1,46 @@ +use zksync_types::{address_to_u256, h256_to_u256, U256}; + +use super::BootloaderState; +use crate::{interface::L1BatchEnv, vm_latest::utils::fee::get_batch_base_fee}; + +const OPERATOR_ADDRESS_SLOT: usize = 0; +const PREV_BLOCK_HASH_SLOT: usize = 1; +const NEW_BLOCK_TIMESTAMP_SLOT: usize = 2; +const NEW_BLOCK_NUMBER_SLOT: usize = 3; +const FAIR_PUBDATA_PRICE_SLOT: usize = 4; +const FAIR_L2_GAS_PRICE_SLOT: usize = 5; +const EXPECTED_BASE_FEE_SLOT: usize = 6; +const SHOULD_SET_NEW_BLOCK_SLOT: usize = 7; + +impl BootloaderState { + /// Returns the initial memory for the bootloader based on the current batch environment. + pub(crate) fn initial_memory(l1_batch: &L1BatchEnv) -> Vec<(usize, U256)> { + let (prev_block_hash, should_set_new_block) = l1_batch + .previous_batch_hash + .map(|prev_block_hash| (h256_to_u256(prev_block_hash), U256::one())) + .unwrap_or_default(); + + vec![ + ( + OPERATOR_ADDRESS_SLOT, + address_to_u256(&l1_batch.fee_account), + ), + (PREV_BLOCK_HASH_SLOT, prev_block_hash), + (NEW_BLOCK_TIMESTAMP_SLOT, U256::from(l1_batch.timestamp)), + (NEW_BLOCK_NUMBER_SLOT, U256::from(l1_batch.number.0)), + ( + FAIR_PUBDATA_PRICE_SLOT, + U256::from(l1_batch.fee_input.fair_pubdata_price()), + ), + ( + FAIR_L2_GAS_PRICE_SLOT, + U256::from(l1_batch.fee_input.fair_l2_gas_price()), + ), + ( + EXPECTED_BASE_FEE_SLOT, + U256::from(get_batch_base_fee(l1_batch)), + ), + (SHOULD_SET_NEW_BLOCK_SLOT, should_set_new_block), + ] + } +} diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/l2_block.rs b/core/lib/multivm/src/versions/vm_latest/bootloader/l2_block.rs similarity index 97% rename from core/lib/multivm/src/versions/vm_latest/bootloader_state/l2_block.rs rename to core/lib/multivm/src/versions/vm_latest/bootloader/l2_block.rs index 95502b8dc60c..922f5384ab3f 100644 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/l2_block.rs +++ b/core/lib/multivm/src/versions/vm_latest/bootloader/l2_block.rs @@ -5,7 +5,7 @@ use zksync_types::{web3::keccak256_concat, L2BlockNumber, H256}; use crate::{ interface::{L2Block, L2BlockEnv}, vm_latest::{ - bootloader_state::{snapshot::L2BlockSnapshot, tx::BootloaderTx}, + bootloader::{snapshot::L2BlockSnapshot, tx::BootloaderTx}, utils::l2_blocks::l2_block_hash, }, }; diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader/mod.rs b/core/lib/multivm/src/versions/vm_latest/bootloader/mod.rs new file mode 100644 index 000000000000..02f67f322f0c --- /dev/null +++ b/core/lib/multivm/src/versions/vm_latest/bootloader/mod.rs @@ -0,0 +1,9 @@ +pub(crate) use self::snapshot::BootloaderStateSnapshot; +pub use self::state::BootloaderState; + +mod init; +mod l2_block; +mod snapshot; +mod state; +mod tx; +pub(crate) mod utils; diff --git a/core/lib/multivm/src/versions/vm_fast/bootloader_state/snapshot.rs b/core/lib/multivm/src/versions/vm_latest/bootloader/snapshot.rs similarity index 100% rename from core/lib/multivm/src/versions/vm_fast/bootloader_state/snapshot.rs rename to core/lib/multivm/src/versions/vm_latest/bootloader/snapshot.rs diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_latest/bootloader/state.rs similarity index 99% rename from core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs rename to core/lib/multivm/src/versions/vm_latest/bootloader/state.rs index 8897ed2dc6e0..0b65d961d3ac 100644 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_latest/bootloader/state.rs @@ -11,13 +11,13 @@ use crate::{ TxExecutionMode, }, vm_latest::{ - bootloader_state::{ + bootloader::{ l2_block::BootloaderL2Block, snapshot::BootloaderStateSnapshot, utils::{apply_l2_block, apply_tx_to_memory}, }, constants::get_tx_description_offset, - types::internals::TransactionData, + types::TransactionData, utils::l2_blocks::assert_next_block, MultiVmSubversion, }, diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/tx.rs b/core/lib/multivm/src/versions/vm_latest/bootloader/tx.rs similarity index 98% rename from core/lib/multivm/src/versions/vm_latest/bootloader_state/tx.rs rename to core/lib/multivm/src/versions/vm_latest/bootloader/tx.rs index 2c63db7e4354..00c7ae43c58f 100644 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/tx.rs +++ b/core/lib/multivm/src/versions/vm_latest/bootloader/tx.rs @@ -1,6 +1,6 @@ use zksync_types::{L2ChainId, H256, U256}; -use crate::{interface::CompressedBytecodeInfo, vm_latest::types::internals::TransactionData}; +use crate::{interface::CompressedBytecodeInfo, vm_latest::types::TransactionData}; /// Information about tx necessary for execution in bootloader. #[derive(Debug, Clone)] diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_latest/bootloader/utils.rs similarity index 99% rename from core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs rename to core/lib/multivm/src/versions/vm_latest/bootloader/utils.rs index 77a8ef3a1a71..e309c6c45acb 100644 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_latest/bootloader/utils.rs @@ -8,7 +8,7 @@ use crate::{ }, utils::bytecode, vm_latest::{ - bootloader_state::l2_block::BootloaderL2Block, + bootloader::l2_block::BootloaderL2Block, constants::{ get_bootloader_tx_description_offset, get_compressed_bytecodes_offset, get_operator_provided_l1_messenger_pubdata_offset, get_operator_refunds_offset, diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/mod.rs b/core/lib/multivm/src/versions/vm_latest/bootloader_state/mod.rs deleted file mode 100644 index 73830de2759b..000000000000 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod l2_block; -mod snapshot; -mod state; -mod tx; - -pub(crate) mod utils; -pub(crate) use snapshot::BootloaderStateSnapshot; -pub use state::BootloaderState; diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/snapshot.rs b/core/lib/multivm/src/versions/vm_latest/bootloader_state/snapshot.rs deleted file mode 100644 index 8f1cec3cb7f1..000000000000 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/snapshot.rs +++ /dev/null @@ -1,25 +0,0 @@ -use zksync_types::H256; - -#[derive(Debug, Clone)] -pub(crate) struct BootloaderStateSnapshot { - /// ID of the next transaction to be executed. - pub(crate) tx_to_execute: usize, - /// Stored L2 blocks in bootloader memory - pub(crate) l2_blocks_len: usize, - /// Snapshot of the last L2 block. Only this block could be changed during the rollback - pub(crate) last_l2_block: L2BlockSnapshot, - /// The number of 32-byte words spent on the already included compressed bytecodes. - pub(crate) compressed_bytecodes_encoding: usize, - /// Current offset of the free space in the bootloader memory. - pub(crate) free_tx_offset: usize, - /// Whether the pubdata information has been provided already - pub(crate) is_pubdata_information_provided: bool, -} - -#[derive(Debug, Clone)] -pub(crate) struct L2BlockSnapshot { - /// The rolling hash of all the transactions in the miniblock - pub(crate) txs_rolling_hash: H256, - /// The number of transactions in the last L2 block - pub(crate) txs_len: usize, -} diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/snapshots.rs b/core/lib/multivm/src/versions/vm_latest/implementation/snapshots.rs index 377c4f548b06..82ea5829342b 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/snapshots.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/snapshots.rs @@ -7,7 +7,7 @@ use crate::{ interface::storage::WriteStorage, vm_latest::{ old_vm::{history_recorder::HistoryEnabled, oracles::OracleWithHistory}, - types::internals::VmSnapshot, + types::VmSnapshot, vm::Vm, }, }; diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/tx.rs b/core/lib/multivm/src/versions/vm_latest/implementation/tx.rs index 6dd73866adf2..02adcc3cdad8 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/tx.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/tx.rs @@ -6,7 +6,7 @@ use crate::{ vm_latest::{ constants::BOOTLOADER_HEAP_PAGE, implementation::bytecode::{bytecode_to_factory_dep, compress_bytecodes}, - types::internals::TransactionData, + types::TransactionData, vm::Vm, }, HistoryMode, diff --git a/core/lib/multivm/src/versions/vm_latest/mod.rs b/core/lib/multivm/src/versions/vm_latest/mod.rs index 46f8db789ddc..4e739efe9516 100644 --- a/core/lib/multivm/src/versions/vm_latest/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/mod.rs @@ -1,6 +1,5 @@ -pub(crate) use self::vm::MultiVmSubversion; pub use self::{ - bootloader_state::BootloaderState, + bootloader::BootloaderState, old_vm::{ history_recorder::{ AppDataFrameManagerWithHistory, HistoryDisabled, HistoryEnabled, HistoryMode, @@ -12,12 +11,16 @@ pub use self::{ dispatcher::TracerDispatcher, traits::{ToTracerPointer, TracerPointer, VmTracer}, }, - types::internals::ZkSyncVmState, + types::ZkSyncVmState, utils::transaction_encoding::TransactionVmExt, vm::Vm, }; +pub(crate) use self::{ + types::{TransactionData, VmHook}, + vm::MultiVmSubversion, +}; -mod bootloader_state; +pub(crate) mod bootloader; pub mod constants; mod implementation; mod old_vm; diff --git a/core/lib/multivm/src/versions/vm_latest/old_vm/history_recorder.rs b/core/lib/multivm/src/versions/vm_latest/old_vm/history_recorder.rs index 9dac6480dc57..7e16382861c5 100644 --- a/core/lib/multivm/src/versions/vm_latest/old_vm/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_latest/old_vm/history_recorder.rs @@ -820,8 +820,12 @@ impl HistoryRecorder { self.apply_historic_record(StorageHistoryRecord { key, value }, timestamp) } - pub(crate) fn drain_inner(&mut self) -> Vec<(StorageKey, U256)> { - self.inner.inner.drain().collect() + pub(crate) fn clone_vec(&mut self) -> Vec<(StorageKey, U256)> { + self.inner + .inner + .iter() + .map(|(key, value)| (*key, *value)) + .collect() } } diff --git a/core/lib/multivm/src/versions/vm_latest/old_vm/utils.rs b/core/lib/multivm/src/versions/vm_latest/old_vm/utils.rs index c020d1db000a..aa5155fc003b 100644 --- a/core/lib/multivm/src/versions/vm_latest/old_vm/utils.rs +++ b/core/lib/multivm/src/versions/vm_latest/old_vm/utils.rs @@ -10,7 +10,7 @@ use zksync_types::{Address, U256}; use crate::{ interface::storage::WriteStorage, - vm_latest::{old_vm::memory::SimpleMemory, types::internals::ZkSyncVmState, HistoryMode}, + vm_latest::{old_vm::memory::SimpleMemory, types::ZkSyncVmState, HistoryMode}, }; #[derive(Debug, Clone)] diff --git a/core/lib/multivm/src/versions/vm_latest/oracles/storage.rs b/core/lib/multivm/src/versions/vm_latest/oracles/storage.rs index 242cdc6a2239..5c8fe1d2a97f 100644 --- a/core/lib/multivm/src/versions/vm_latest/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_latest/oracles/storage.rs @@ -576,7 +576,7 @@ impl VmStorageOracle for StorageOracle { // Note that while the history is preserved, the inner parts are fully cleared out. // TODO(X): potentially optimize this function by allowing rollbacks only at the bounds of transactions. - let current_active_keys = self.transient_storage.drain_inner(); + let current_active_keys = self.transient_storage.clone_vec(); for (key, current_value) in current_active_keys { self.write_transient_storage_value(ReducedTstoreLogQuery { // We currently only support rollup shard id diff --git a/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs index c8f623478569..451647545671 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs @@ -1,15 +1,14 @@ use std::sync::Arc; use once_cell::sync::OnceCell; -use zksync_test_contracts::TestContract; use zksync_types::{Address, Execute}; use super::TestedLatestVm; use crate::{ interface::{InspectExecutionMode, TxExecutionMode, VmInterface}, tracers::CallTracer, - versions::testonly::{read_max_depth_contract, ContractToDeploy, VmTesterBuilder}, - vm_latest::{constants::BATCH_COMPUTATIONAL_GAS_LIMIT, ToTracerPointer}, + versions::testonly::{call_tracer, read_max_depth_contract, ContractToDeploy, VmTesterBuilder}, + vm_latest::{constants::BATCH_COMPUTATIONAL_GAS_LIMIT, ToTracerPointer, Vm}, }; // This test is ultra slow, so it's ignored by default. @@ -48,43 +47,31 @@ fn test_max_depth() { } #[test] -fn test_basic_behavior() { - let contract = TestContract::counter().bytecode.to_vec(); - let address = Address::repeat_byte(1); - let mut vm = VmTesterBuilder::new() - .with_empty_in_memory_storage() - .with_rich_accounts(1) - .with_bootloader_gas_limit(BATCH_COMPUTATIONAL_GAS_LIMIT) - .with_execution_mode(TxExecutionMode::VerifyExecute) - .with_custom_contracts(vec![ContractToDeploy::account(contract, address)]) - .build::(); +fn basic_behavior() { + call_tracer::test_basic_behavior::>(); +} - let increment_by_6_calldata = - "7cf5dab00000000000000000000000000000000000000000000000000000000000000006"; +#[test] +fn transfer() { + call_tracer::test_transfer::>(); +} - let account = &mut vm.rich_accounts[0]; - let tx = account.get_l2_tx_for_execute( - Execute { - contract_address: Some(address), - calldata: hex::decode(increment_by_6_calldata).unwrap(), - value: Default::default(), - factory_deps: vec![], - }, - None, - ); +#[test] +fn reverted_tx() { + call_tracer::test_reverted_tx::>(); +} - let result = Arc::new(OnceCell::new()); - let call_tracer = CallTracer::new(result.clone()).into_tracer_pointer(); - vm.vm.push_transaction(tx); - let res = vm - .vm - .inspect(&mut call_tracer.into(), InspectExecutionMode::OneTx); +#[test] +fn reverted_deployment() { + call_tracer::test_reverted_deployment_tx::>(); +} - let call_tracer_result = result.get().unwrap(); +#[test] +fn out_of_gas() { + call_tracer::test_out_of_gas::>(); +} - assert_eq!(call_tracer_result.len(), 1); - // Expect that there are a plenty of subcalls underneath. - let subcall = &call_tracer_result[0].calls; - assert!(subcall.len() > 10); - assert!(!res.result.is_failed()); +#[test] +fn recursive_tx() { + call_tracer::test_recursive_tx::>(); } diff --git a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs index 0a89ddb0bf50..260b1a4eeef3 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs @@ -4,6 +4,7 @@ use std::{ sync::Arc, }; +use once_cell::sync::OnceCell; use zk_evm_1_5_0::{ aux_structures::{MemoryPage, Timestamp}, vm_state::VmLocalState, @@ -13,7 +14,7 @@ use zksync_types::{ bytecode::BytecodeHash, l2::L2Tx, vm::VmVersion, writes::StateDiffRecord, StorageKey, StorageValue, Transaction, H256, U256, }; -use zksync_vm_interface::VmInterface; +use zksync_vm_interface::{Call, InspectExecutionMode, VmInterface}; use super::{HistoryEnabled, ToTracerPointer, Vm}; use crate::{ @@ -23,16 +24,17 @@ use crate::{ tracer::ViolatedValidationRule, CurrentExecutionState, L2BlockEnv, VmExecutionMode, VmExecutionResultAndLogs, }, - tracers::ValidationTracer, + tracers::{CallTracer, ValidationTracer}, utils::bytecode::bytes_to_be_words, versions::testonly::{ filter_out_base_system_contracts, validation_params, TestedVm, TestedVmForValidation, + TestedVmWithCallTracer, }, vm_latest::{ constants::BOOTLOADER_HEAP_PAGE, old_vm::{event_sink::InMemoryEventSink, history_recorder::HistoryRecorder}, tracers::PubdataTracer, - types::internals::TransactionData, + types::TransactionData, utils::logs::StorageLogQuery, AppDataFrameManagerWithHistory, HistoryMode, SimpleMemory, TracerDispatcher, }, @@ -338,3 +340,13 @@ impl Vm (VmExecutionResultAndLogs, Vec) { + let result = Arc::new(OnceCell::new()); + let call_tracer = CallTracer::new(result.clone()).into_tracer_pointer(); + let res = self.inspect(&mut call_tracer.into(), InspectExecutionMode::OneTx); + let traces = result.get().unwrap().clone(); + (res, traces) + } +} diff --git a/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs b/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs index f126a7f8fbdd..5b99fc4558ed 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs @@ -18,7 +18,7 @@ use crate::{ VmTesterBuilder, }, vm_latest::{ - types::internals::ZkSyncVmState, BootloaderState, HistoryEnabled, HistoryMode, + bootloader::BootloaderState, types::ZkSyncVmState, HistoryEnabled, HistoryMode, SimpleMemory, ToTracerPointer, Vm, VmTracer, }, }; diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/circuits_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/circuits_tracer.rs index 6a47f3ae2fbe..059c9e67eeb3 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/circuits_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/circuits_tracer.rs @@ -15,10 +15,10 @@ use crate::{ tracers::dynamic::vm_1_5_0::DynTracer, utils::CircuitCycleStatistic, vm_latest::{ - bootloader_state::BootloaderState, + bootloader::BootloaderState, old_vm::{history_recorder::HistoryMode, memory::SimpleMemory}, tracers::traits::VmTracer, - types::internals::ZkSyncVmState, + types::ZkSyncVmState, }, }; diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/default_tracers.rs b/core/lib/multivm/src/versions/vm_latest/tracers/default_tracers.rs index 08ff79524b87..05afbbdb398c 100755 --- a/core/lib/multivm/src/versions/vm_latest/tracers/default_tracers.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/default_tracers.rs @@ -23,17 +23,17 @@ use crate::{ }, tracers::dynamic::vm_1_5_0::DynTracer, vm_latest::{ - bootloader_state::{utils::apply_l2_block, BootloaderState}, + bootloader::{utils::apply_l2_block, BootloaderState}, constants::BOOTLOADER_HEAP_PAGE, old_vm::{history_recorder::HistoryMode, memory::SimpleMemory}, tracers::{ dispatcher::TracerDispatcher, - utils::{computational_gas_price, print_debug_if_needed, VmHook}, + utils::{computational_gas_price, print_debug_log, print_debug_returndata}, CircuitsTracer, RefundsTracer, ResultTracer, }, - types::internals::ZkSyncVmState, + types::ZkSyncVmState, vm::MultiVmSubversion, - VmTracer, + VmHook, VmTracer, }, }; @@ -220,22 +220,18 @@ impl Tracer for DefaultExecutionTracer { } let hook = VmHook::from_opcode_memory(&state, &data, self.subversion); - print_debug_if_needed( - &hook, - &state, - memory, - self.result_tracer.get_latest_result_ptr(), - self.subversion, - ); - match hook { - VmHook::TxHasEnded if matches!(self.execution_mode, VmExecutionMode::OneTx) => { + Some(VmHook::TxHasEnded) if matches!(self.execution_mode, VmExecutionMode::OneTx) => { self.result_tracer.tx_finished_in_one_tx_mode = true; self.tx_has_been_processed = true; } - VmHook::NoValidationEntered => self.in_account_validation = false, - VmHook::AccountValidationEntered => self.in_account_validation = true, - VmHook::FinalBatchInfo => self.final_batch_info_requested = true, + Some(VmHook::ValidationExited) => self.in_account_validation = false, + Some(VmHook::AccountValidationEntered) => self.in_account_validation = true, + Some(VmHook::FinalBatchInfo) => self.final_batch_info_requested = true, + Some(VmHook::DebugLog) => print_debug_log(&state, memory, self.subversion), + Some(VmHook::DebugReturnData) => { + print_debug_returndata(memory, self.result_tracer.get_latest_result_ptr()) + } _ => {} } diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/dispatcher.rs b/core/lib/multivm/src/versions/vm_latest/tracers/dispatcher.rs index 3c3ef1173f53..41ff237551f4 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/dispatcher.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/dispatcher.rs @@ -9,7 +9,8 @@ use crate::{ }, tracers::dynamic::vm_1_5_0::DynTracer, vm_latest::{ - BootloaderState, HistoryMode, SimpleMemory, TracerPointer, VmTracer, ZkSyncVmState, + bootloader::BootloaderState, HistoryMode, SimpleMemory, TracerPointer, VmTracer, + ZkSyncVmState, }, }; diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/evm_deploy_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/evm_deploy_tracer.rs index dd03a9427efa..70e055343e61 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/evm_deploy_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/evm_deploy_tracer.rs @@ -19,7 +19,7 @@ use crate::{ }, tracers::dynamic::vm_1_5_0::DynTracer, utils::bytecode::bytes_to_be_words, - vm_latest::{BootloaderState, HistoryMode, SimpleMemory, ZkSyncVmState}, + vm_latest::{bootloader::BootloaderState, HistoryMode, SimpleMemory, ZkSyncVmState}, }; /// Tracer responsible for collecting information about EVM deploys and providing those diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs index 31309e6ff062..f1f41a2ef3d3 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs @@ -27,14 +27,14 @@ use crate::{ }, }, vm_latest::{ - bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, + bootloader::{utils::apply_pubdata_to_memory, BootloaderState}, constants::BOOTLOADER_HEAP_PAGE, old_vm::{history_recorder::HistoryMode, memory::SimpleMemory}, - tracers::{traits::VmTracer, utils::VmHook}, - types::internals::ZkSyncVmState, + tracers::traits::VmTracer, + types::ZkSyncVmState, utils::logs::collect_events_and_l1_system_logs_after_timestamp, vm::MultiVmSubversion, - StorageOracle, + StorageOracle, VmHook, }, }; @@ -207,7 +207,7 @@ impl DynTracer> for PubdataTracer { _storage: StoragePtr, ) { let hook = VmHook::from_opcode_memory(&state, &data, self.subversion); - if let VmHook::PubdataRequested = hook { + if matches!(hook, Some(VmHook::PubdataRequested)) { self.pubdata_info_requested = true; } } diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs index 2bd08e094327..071c0ac37718 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs @@ -5,7 +5,7 @@ use zk_evm_1_5_0::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, }; -use zksync_types::{ceil_div_u256, H256, U256}; +use zksync_types::H256; use crate::{ interface::{ @@ -15,16 +15,14 @@ use crate::{ }, tracers::dynamic::vm_1_5_0::DynTracer, vm_latest::{ - bootloader_state::BootloaderState, + bootloader::BootloaderState, constants::{get_operator_refunds_offset, BOOTLOADER_HEAP_PAGE, TX_GAS_LIMIT_OFFSET}, old_vm::{history_recorder::HistoryMode, memory::SimpleMemory}, - tracers::{ - traits::VmTracer, - utils::{get_vm_hook_params, VmHook}, - }, - types::internals::ZkSyncVmState, - utils::fee::get_batch_base_fee, + tracers::{traits::VmTracer, utils::get_vm_hook_params}, + types::ZkSyncVmState, + utils::refund::compute_refund, vm::MultiVmSubversion, + VmHook, }, }; @@ -101,58 +99,15 @@ impl RefundsTracer { pubdata_published: u32, tx_hash: H256, ) -> u64 { - let total_gas_spent = tx_gas_limit - bootloader_refund; - - let gas_spent_on_computation = total_gas_spent - .checked_sub(gas_spent_on_pubdata) - .unwrap_or_else(|| { - tracing::error!( - "Gas spent on pubdata is greater than total gas spent. On pubdata: {}, total: {}", - gas_spent_on_pubdata, - total_gas_spent - ); - 0 - }); - - // For now, bootloader charges only for base fee. - let effective_gas_price = get_batch_base_fee(&self.l1_batch); - - let bootloader_eth_price_per_pubdata_byte = - U256::from(effective_gas_price) * U256::from(current_ergs_per_pubdata_byte); - - let fair_eth_price_per_pubdata_byte = - U256::from(self.l1_batch.fee_input.fair_pubdata_price()); - - // For now, L1 originated transactions are allowed to pay less than fair fee per pubdata, - // so we should take it into account. - let eth_price_per_pubdata_byte_for_calculation = std::cmp::min( - bootloader_eth_price_per_pubdata_byte, - fair_eth_price_per_pubdata_byte, - ); - - let fair_fee_eth = U256::from(gas_spent_on_computation) - * U256::from(self.l1_batch.fee_input.fair_l2_gas_price()) - + U256::from(pubdata_published) * eth_price_per_pubdata_byte_for_calculation; - let pre_paid_eth = U256::from(tx_gas_limit) * U256::from(effective_gas_price); - let refund_eth = pre_paid_eth.checked_sub(fair_fee_eth).unwrap_or_else(|| { - tracing::error!( - "Fair fee is greater than pre paid. Fair fee: {} wei, pre paid: {} wei", - fair_fee_eth, - pre_paid_eth - ); - U256::zero() - }); - - tracing::trace!( - "Fee benchmark for transaction with hash {}", - hex::encode(tx_hash.as_bytes()) - ); - tracing::trace!("Gas Limit: {}", tx_gas_limit); - tracing::trace!("Gas spent on computation: {}", gas_spent_on_computation); - tracing::trace!("Gas spent on pubdata: {}", gas_spent_on_pubdata); - tracing::trace!("Pubdata published: {}", pubdata_published); - - ceil_div_u256(refund_eth, effective_gas_price.into()).as_u64() + compute_refund( + &self.l1_batch, + bootloader_refund, + gas_spent_on_pubdata, + tx_gas_limit, + current_ergs_per_pubdata_byte, + pubdata_published, + tx_hash, + ) } pub(crate) fn pubdata_published(&self) -> u32 { @@ -171,16 +126,16 @@ impl DynTracer> for RefundsTracer { self.timestamp_before_cycle = Timestamp(state.vm_local_state.timestamp); let hook = VmHook::from_opcode_memory(&state, &data, self.subversion); match hook { - VmHook::NotifyAboutRefund => { - self.refund_gas = get_vm_hook_params(memory, self.subversion)[0].as_u64() + Some(VmHook::NotifyAboutRefund) => { + self.refund_gas = get_vm_hook_params(memory, self.subversion)[0].as_u64(); } - VmHook::AskOperatorForRefund => { + Some(VmHook::AskOperatorForRefund) => { self.pending_refund_request = Some(RefundRequest { refund: get_vm_hook_params(memory, self.subversion)[0].as_u64(), gas_spent_on_pubdata: get_vm_hook_params(memory, self.subversion)[1].as_u64(), used_gas_per_pubdata_byte: get_vm_hook_params(memory, self.subversion)[2] .as_u32(), - }) + }); } _ => {} } diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/result_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/result_tracer.rs index 80a3147f65d2..a90c7c8a018a 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/result_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/result_tracer.rs @@ -16,15 +16,16 @@ use crate::{ }, tracers::dynamic::vm_1_5_0::DynTracer, vm_latest::{ + bootloader::BootloaderState, constants::{get_result_success_first_slot, BOOTLOADER_HEAP_PAGE}, old_vm::utils::{vm_may_have_ended_inner, VmExecutionResult}, tracers::{ traits::VmTracer, - utils::{get_vm_hook_params, read_pointer, VmHook}, + utils::{get_vm_hook_params, read_pointer}, }, - types::internals::ZkSyncVmState, + types::ZkSyncVmState, vm::MultiVmSubversion, - BootloaderState, HistoryMode, SimpleMemory, + HistoryMode, SimpleMemory, VmHook, }, }; @@ -155,7 +156,7 @@ impl DynTracer> for ResultTracer { _storage: StoragePtr, ) { let hook = VmHook::from_opcode_memory(&state, &data, self.subversion); - if let VmHook::ExecutionResult = hook { + if matches!(hook, Some(VmHook::PostResult)) { let vm_hook_params = get_vm_hook_params(memory, self.subversion); let success = vm_hook_params[0]; let returndata = self diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/traits.rs b/core/lib/multivm/src/versions/vm_latest/tracers/traits.rs index 76dab3dd70a1..b85f8e3ca4e0 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/traits.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/traits.rs @@ -5,9 +5,9 @@ use crate::{ }, tracers::dynamic::vm_1_5_0::DynTracer, vm_latest::{ - bootloader_state::BootloaderState, + bootloader::BootloaderState, old_vm::{history_recorder::HistoryMode, memory::SimpleMemory}, - types::internals::ZkSyncVmState, + types::ZkSyncVmState, }, }; diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs b/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs index 6f81a3ac8de5..ced3193ca490 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs @@ -22,33 +22,15 @@ use crate::vm_latest::{ utils::{aux_heap_page_from_base, heap_page_from_base}, }, vm::MultiVmSubversion, + VmHook, }; -#[derive(Clone, Debug, Copy)] -pub(crate) enum VmHook { - AccountValidationEntered, - PaymasterValidationEntered, - NoValidationEntered, - ValidationStepEndeded, - TxHasEnded, - DebugLog, - DebugReturnData, - NoHook, - NearCallCatch, - AskOperatorForRefund, - NotifyAboutRefund, - ExecutionResult, - FinalBatchInfo, - // Hook used to signal that the final pubdata for a batch is requested. - PubdataRequested, -} - impl VmHook { pub(crate) fn from_opcode_memory( state: &VmLocalStateData<'_>, data: &BeforeExecutionData, subversion: MultiVmSubversion, - ) -> Self { + ) -> Option { let opcode_variant = data.opcode.variant; let heap_page = heap_page_from_base(state.vm_local_state.callstack.current.base_memory_page).0; @@ -64,33 +46,18 @@ impl VmHook { || heap_page != BOOTLOADER_HEAP_PAGE || fat_ptr.offset != get_vm_hook_position(subversion) * 32 { - return Self::NoHook; + return None; } - match value.as_u32() { - 0 => Self::AccountValidationEntered, - 1 => Self::PaymasterValidationEntered, - 2 => Self::NoValidationEntered, - 3 => Self::ValidationStepEndeded, - 4 => Self::TxHasEnded, - 5 => Self::DebugLog, - 6 => Self::DebugReturnData, - 7 => Self::NearCallCatch, - 8 => Self::AskOperatorForRefund, - 9 => Self::NotifyAboutRefund, - 10 => Self::ExecutionResult, - 11 => Self::FinalBatchInfo, - 12 => Self::PubdataRequested, - _ => panic!("Unknown hook: {}", value.as_u32()), - } + Some(Self::new(value.as_u32())) } } -pub(crate) fn get_debug_log( +pub(crate) fn print_debug_log( state: &VmLocalStateData<'_>, memory: &SimpleMemory, subversion: MultiVmSubversion, -) -> String { +) { let vm_hook_params: Vec<_> = get_vm_hook_params(memory, subversion) .into_iter() .map(u256_to_h256) @@ -113,7 +80,7 @@ pub(crate) fn get_debug_log( data.to_string() }; let tx_id = state.vm_local_state.tx_number_in_block; - format!("Bootloader transaction {tx_id}: {msg}: {data_str}") + tracing::trace!("Bootloader transaction {tx_id}: {msg}: {data_str}"); } /// Reads the memory slice represented by the fat pointer. @@ -142,33 +109,17 @@ pub(crate) fn read_pointer( /// Outputs the returndata for the latest call. /// This is usually used to output the revert reason. -pub(crate) fn get_debug_returndata( +pub(crate) fn print_debug_returndata( memory: &SimpleMemory, latest_returndata_ptr: Option, -) -> String { +) { let returndata = if let Some(ptr) = latest_returndata_ptr { read_pointer(memory, ptr) } else { vec![] }; - format!("0x{}", hex::encode(returndata)) -} - -/// Accepts a vm hook and, if it requires to output some debug log, outputs it. -pub(crate) fn print_debug_if_needed( - hook: &VmHook, - state: &VmLocalStateData<'_>, - memory: &SimpleMemory, - latest_returndata_ptr: Option, - subversion: MultiVmSubversion, -) { - let log = match hook { - VmHook::DebugLog => get_debug_log(state, memory, subversion), - VmHook::DebugReturnData => get_debug_returndata(memory, latest_returndata_ptr), - _ => return, - }; - tracing::trace!("{log}"); + tracing::trace!("0x{}", hex::encode(returndata)); } pub(crate) fn computational_gas_price( diff --git a/core/lib/multivm/src/versions/vm_latest/types/hook.rs b/core/lib/multivm/src/versions/vm_latest/types/hook.rs new file mode 100644 index 000000000000..1fbd0c826e5e --- /dev/null +++ b/core/lib/multivm/src/versions/vm_latest/types/hook.rs @@ -0,0 +1,39 @@ +#[derive(Debug, Copy, Clone)] +pub(crate) enum VmHook { + AccountValidationEntered, + PaymasterValidationEntered, + ValidationExited, + ValidationStepEnded, + TxHasEnded, + DebugLog, + DebugReturnData, + NearCallCatch, + AskOperatorForRefund, + NotifyAboutRefund, + PostResult, + FinalBatchInfo, + PubdataRequested, +} + +impl VmHook { + /// # Panics + /// Panics if the number does not correspond to any hook. + pub fn new(raw: u32) -> Self { + match raw { + 0 => Self::AccountValidationEntered, + 1 => Self::PaymasterValidationEntered, + 2 => Self::ValidationExited, + 3 => Self::ValidationStepEnded, + 4 => Self::TxHasEnded, + 5 => Self::DebugLog, + 6 => Self::DebugReturnData, + 7 => Self::NearCallCatch, + 8 => Self::AskOperatorForRefund, + 9 => Self::NotifyAboutRefund, + 10 => Self::PostResult, + 11 => Self::FinalBatchInfo, + 12 => Self::PubdataRequested, + _ => panic!("Unknown hook: {raw}"), + } + } +} diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/mod.rs b/core/lib/multivm/src/versions/vm_latest/types/internals/mod.rs deleted file mode 100644 index 601b7b8bd014..000000000000 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub(crate) use snapshot::VmSnapshot; -pub(crate) use transaction_data::TransactionData; -pub(crate) use vm_state::new_vm_state; -pub use vm_state::ZkSyncVmState; -mod snapshot; -mod transaction_data; -mod vm_state; diff --git a/core/lib/multivm/src/versions/vm_latest/types/l1_batch.rs b/core/lib/multivm/src/versions/vm_latest/types/l1_batch.rs deleted file mode 100644 index 89b22d328ac5..000000000000 --- a/core/lib/multivm/src/versions/vm_latest/types/l1_batch.rs +++ /dev/null @@ -1,43 +0,0 @@ -use zksync_types::{address_to_u256, h256_to_u256, U256}; - -use crate::{interface::L1BatchEnv, vm_latest::utils::fee::get_batch_base_fee}; - -const OPERATOR_ADDRESS_SLOT: usize = 0; -const PREV_BLOCK_HASH_SLOT: usize = 1; -const NEW_BLOCK_TIMESTAMP_SLOT: usize = 2; -const NEW_BLOCK_NUMBER_SLOT: usize = 3; -const FAIR_PUBDATA_PRICE_SLOT: usize = 4; -const FAIR_L2_GAS_PRICE_SLOT: usize = 5; -const EXPECTED_BASE_FEE_SLOT: usize = 6; -const SHOULD_SET_NEW_BLOCK_SLOT: usize = 7; - -/// Returns the initial memory for the bootloader based on the current batch environment. -pub(crate) fn bootloader_initial_memory(l1_batch: &L1BatchEnv) -> Vec<(usize, U256)> { - let (prev_block_hash, should_set_new_block) = l1_batch - .previous_batch_hash - .map(|prev_block_hash| (h256_to_u256(prev_block_hash), U256::one())) - .unwrap_or_default(); - - vec![ - ( - OPERATOR_ADDRESS_SLOT, - address_to_u256(&l1_batch.fee_account), - ), - (PREV_BLOCK_HASH_SLOT, prev_block_hash), - (NEW_BLOCK_TIMESTAMP_SLOT, U256::from(l1_batch.timestamp)), - (NEW_BLOCK_NUMBER_SLOT, U256::from(l1_batch.number.0)), - ( - FAIR_PUBDATA_PRICE_SLOT, - U256::from(l1_batch.fee_input.fair_pubdata_price()), - ), - ( - FAIR_L2_GAS_PRICE_SLOT, - U256::from(l1_batch.fee_input.fair_l2_gas_price()), - ), - ( - EXPECTED_BASE_FEE_SLOT, - U256::from(get_batch_base_fee(l1_batch)), - ), - (SHOULD_SET_NEW_BLOCK_SLOT, should_set_new_block), - ] -} diff --git a/core/lib/multivm/src/versions/vm_latest/types/mod.rs b/core/lib/multivm/src/versions/vm_latest/types/mod.rs index a12005734abb..0963b7c458c0 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/mod.rs @@ -1,2 +1,9 @@ -pub(crate) mod internals; -mod l1_batch; +mod hook; +mod snapshot; +mod transaction_data; +mod vm_state; + +pub use self::vm_state::ZkSyncVmState; +pub(crate) use self::{ + hook::VmHook, snapshot::VmSnapshot, transaction_data::TransactionData, vm_state::new_vm_state, +}; diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/snapshot.rs b/core/lib/multivm/src/versions/vm_latest/types/snapshot.rs similarity index 82% rename from core/lib/multivm/src/versions/vm_latest/types/internals/snapshot.rs rename to core/lib/multivm/src/versions/vm_latest/types/snapshot.rs index 76b466fd605b..b43392b5111a 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/snapshot.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/snapshot.rs @@ -1,6 +1,6 @@ use zk_evm_1_5_0::vm_state::VmLocalState; -use crate::vm_latest::bootloader_state::BootloaderStateSnapshot; +use crate::vm_latest::bootloader::BootloaderStateSnapshot; /// A snapshot of the VM that holds enough information to /// rollback the VM to some historical state. diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_latest/types/transaction_data.rs similarity index 100% rename from core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs rename to core/lib/multivm/src/versions/vm_latest/types/transaction_data.rs diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_latest/types/vm_state.rs similarity index 97% rename from core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs rename to core/lib/multivm/src/versions/vm_latest/types/vm_state.rs index 63f06f4fd846..55b504a85f7c 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/vm_state.rs @@ -20,7 +20,7 @@ use crate::{ }, utils::bytecode::bytes_to_be_words, vm_latest::{ - bootloader_state::BootloaderState, + bootloader::BootloaderState, constants::BOOTLOADER_HEAP_PAGE, old_vm::{ event_sink::InMemoryEventSink, @@ -31,7 +31,6 @@ use crate::{ }, }, oracles::storage::StorageOracle, - types::l1_batch::bootloader_initial_memory, utils::l2_blocks::{assert_next_block, load_last_l2_block}, }, }; @@ -106,7 +105,7 @@ pub(crate) fn new_vm_state( Timestamp(0), ); - let bootloader_initial_memory = bootloader_initial_memory(l1_batch_env); + let bootloader_initial_memory = BootloaderState::initial_memory(l1_batch_env); memory.populate_page( BOOTLOADER_HEAP_PAGE as usize, bootloader_initial_memory.clone(), diff --git a/core/lib/multivm/src/versions/vm_latest/utils/logs.rs b/core/lib/multivm/src/versions/vm_latest/utils/logs.rs index dfa23685dcda..9e4c61ab059c 100644 --- a/core/lib/multivm/src/versions/vm_latest/utils/logs.rs +++ b/core/lib/multivm/src/versions/vm_latest/utils/logs.rs @@ -6,7 +6,7 @@ use crate::{ interface::{storage::WriteStorage, L1BatchEnv, VmEvent}, vm_latest::{ old_vm::{events::merge_events, history_recorder::HistoryMode}, - types::internals::ZkSyncVmState, + types::ZkSyncVmState, }, }; diff --git a/core/lib/multivm/src/versions/vm_latest/utils/mod.rs b/core/lib/multivm/src/versions/vm_latest/utils/mod.rs index 97483633bc54..04821d411f84 100644 --- a/core/lib/multivm/src/versions/vm_latest/utils/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/utils/mod.rs @@ -6,6 +6,7 @@ pub mod fee; pub mod l2_blocks; pub(crate) mod logs; pub mod overhead; +pub(crate) mod refund; pub mod transaction_encoding; pub const fn heap_page_from_base(base: MemoryPage) -> MemoryPage { diff --git a/core/lib/multivm/src/versions/vm_fast/refund.rs b/core/lib/multivm/src/versions/vm_latest/utils/refund.rs similarity index 100% rename from core/lib/multivm/src/versions/vm_fast/refund.rs rename to core/lib/multivm/src/versions/vm_latest/utils/refund.rs diff --git a/core/lib/multivm/src/versions/vm_latest/utils/transaction_encoding.rs b/core/lib/multivm/src/versions/vm_latest/utils/transaction_encoding.rs index ed532f89dbc6..515f436df89c 100644 --- a/core/lib/multivm/src/versions/vm_latest/utils/transaction_encoding.rs +++ b/core/lib/multivm/src/versions/vm_latest/utils/transaction_encoding.rs @@ -1,6 +1,6 @@ use zksync_types::Transaction; -use crate::vm_latest::types::internals::TransactionData; +use crate::vm_latest::types::TransactionData; /// Extension for transactions, specific for VM. Required for bypassing the orphan rule pub trait TransactionVmExt { diff --git a/core/lib/multivm/src/versions/vm_latest/vm.rs b/core/lib/multivm/src/versions/vm_latest/vm.rs index 3914bfca17a2..9eb342a6c8d6 100644 --- a/core/lib/multivm/src/versions/vm_latest/vm.rs +++ b/core/lib/multivm/src/versions/vm_latest/vm.rs @@ -21,10 +21,10 @@ use crate::{ }, utils::{bytecode::be_words_to_bytes, events::extract_l2tol1logs_from_l1_messenger}, vm_latest::{ - bootloader_state::BootloaderState, + bootloader::BootloaderState, old_vm::{events::merge_events, history_recorder::HistoryEnabled}, tracers::{dispatcher::TracerDispatcher, PubdataTracer}, - types::internals::{new_vm_state, VmSnapshot, ZkSyncVmState}, + types::{new_vm_state, VmSnapshot, ZkSyncVmState}, }, HistoryMode, }; diff --git a/core/lib/prover_interface/Cargo.toml b/core/lib/prover_interface/Cargo.toml index 533e3bc1296a..dfa860c5aa6b 100644 --- a/core/lib/prover_interface/Cargo.toml +++ b/core/lib/prover_interface/Cargo.toml @@ -18,6 +18,7 @@ zksync_types.workspace = true # We can use the newest api to send proofs to L1. circuit_definitions.workspace = true fflonk.workspace = true +bellman.workspace = true circuit_sequencer_api.workspace = true serde.workspace = true diff --git a/core/lib/prover_interface/src/outputs.rs b/core/lib/prover_interface/src/outputs.rs index b536c39778a5..3fc037d0c040 100644 --- a/core/lib/prover_interface/src/outputs.rs +++ b/core/lib/prover_interface/src/outputs.rs @@ -1,10 +1,12 @@ use core::fmt; +use bellman::plonk::better_better_cs::proof::Proof as PlonkProof; use circuit_definitions::{ boojum::pairing::bn256::Bn256, - circuit_definitions::aux_layer::ZkSyncSnarkWrapperCircuitNoLookupCustomGate, + circuit_definitions::aux_layer::{ + ZkSyncSnarkWrapperCircuit, ZkSyncSnarkWrapperCircuitNoLookupCustomGate, + }, }; -use circuit_sequencer_api::proof::FinalProof; use fflonk::FflonkProof; use serde::{Deserialize, Serialize}; use serde_with::{hex::Hex, serde_as}; @@ -13,6 +15,7 @@ use zksync_types::{protocol_version::ProtocolSemanticVersion, tee_types::TeeType /// A "final" ZK proof that can be sent to the L1 contract. #[derive(Clone, Serialize, Deserialize)] +#[serde(untagged)] #[allow(clippy::large_enum_variant)] pub enum L1BatchProofForL1 { Fflonk(FflonkL1BatchProofForL1), @@ -42,10 +45,18 @@ pub struct FflonkL1BatchProofForL1 { pub protocol_version: ProtocolSemanticVersion, } +// Implementation created to allow conversion from FflonkL1BatchProofForL1(which is old L1BatchProofForL1) +// to L1BatchProofForL1 to avoid compatibility problems with serialization/deserialization +impl From for L1BatchProofForL1 { + fn from(proof: FflonkL1BatchProofForL1) -> Self { + L1BatchProofForL1::Fflonk(proof) + } +} + #[derive(Clone, Serialize, Deserialize)] pub struct PlonkL1BatchProofForL1 { pub aggregation_result_coords: [[u8; 32]; 4], - pub scheduler_proof: FinalProof, + pub scheduler_proof: PlonkProof, pub protocol_version: ProtocolSemanticVersion, } @@ -124,11 +135,12 @@ impl StoredObject for L1BatchProofForL1 { } fn deserialize(bytes: Vec) -> Result { - zksync_object_store::bincode::deserialize::(&bytes).or_else(|_| { - zksync_object_store::bincode::deserialize::(&bytes) + match zksync_object_store::bincode::deserialize::(&bytes) { + Ok(proof) => Ok(proof.into()), + Err(_) => zksync_object_store::bincode::deserialize::(&bytes) .map(Into::into) - .map_err(Into::into) - }) + .map_err(Into::into), + } } } diff --git a/core/lib/prover_interface/tests/job_serialization.rs b/core/lib/prover_interface/tests/job_serialization.rs index cc78a9acf262..f28a8d94bf0c 100644 --- a/core/lib/prover_interface/tests/job_serialization.rs +++ b/core/lib/prover_interface/tests/job_serialization.rs @@ -102,8 +102,7 @@ fn test_proof_request_serialization() { let encoded_obj = serde_json::to_string(&proof).unwrap(); let encoded_json = r#"{ "Proof": { - "Plonk": { - "aggregation_result_coords": [ + "aggregation_result_coords": [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], @@ -159,7 +158,6 @@ fn test_proof_request_serialization() { }, "protocol_version": "0.25.10" } - } }"#; let decoded_obj: SubmitProofRequest = serde_json::from_str(&encoded_obj).unwrap(); let decoded_json: SubmitProofRequest = serde_json::from_str(encoded_json).unwrap(); diff --git a/core/lib/types/Cargo.toml b/core/lib/types/Cargo.toml index 6af0e39d14f0..f4eeebfce038 100644 --- a/core/lib/types/Cargo.toml +++ b/core/lib/types/Cargo.toml @@ -29,6 +29,7 @@ rlp.workspace = true serde.workspace = true serde_json.workspace = true serde_with = { workspace = true, features = ["hex"] } +ciborium.workspace = true bigdecimal.workspace = true strum = { workspace = true, features = ["derive"] } thiserror.workspace = true diff --git a/core/lib/types/src/contract_verification_api.rs b/core/lib/types/src/contract_verification/api.rs similarity index 92% rename from core/lib/types/src/contract_verification_api.rs rename to core/lib/types/src/contract_verification/api.rs index cca5ae5a83a0..594596070d9f 100644 --- a/core/lib/types/src/contract_verification_api.rs +++ b/core/lib/types/src/contract_verification/api.rs @@ -5,6 +5,7 @@ use serde::{ de::{Deserializer, Error, MapAccess, Unexpected, Visitor}, Deserialize, Serialize, }; +use zksync_basic_types::bytecode::BytecodeMarker; pub use crate::Execute as ExecuteData; use crate::{web3::Bytes, Address}; @@ -232,12 +233,37 @@ impl CompilationArtifacts { } } +/// Non-critical issues detected during verification. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub enum VerificationProblem { + /// The bytecode is correct, but metadata hash is different. + IncorrectMetadata, +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct VerificationInfo { pub request: VerificationRequest, pub artifacts: CompilationArtifacts, pub verified_at: DateTime, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub verification_problems: Vec, +} + +impl VerificationInfo { + pub fn is_perfect_match(&self) -> bool { + self.verification_problems.is_empty() + } + + pub fn bytecode_marker(&self) -> BytecodeMarker { + // Deployed bytecode is only present for EVM contracts. + if self.artifacts.deployed_bytecode.is_some() { + BytecodeMarker::Evm + } else { + BytecodeMarker::EraVm + } + } } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/core/lib/types/src/contract_verification/contract_identifier.rs b/core/lib/types/src/contract_verification/contract_identifier.rs new file mode 100644 index 000000000000..354ddeaa0e29 --- /dev/null +++ b/core/lib/types/src/contract_verification/contract_identifier.rs @@ -0,0 +1,396 @@ +use serde::{Deserialize, Serialize}; + +use crate::{bytecode::BytecodeMarker, web3::keccak256, H256}; + +/// An identifier of the contract bytecode. +/// This identifier can be used to detect different contracts that share the same sources, +/// even if they differ in bytecode verbatim (e.g. if the contract metadata is different). +/// +/// Identifier depends on the marker of the bytecode of the contract. +/// This might be important, since the metadata can be different for EVM and EraVM, +/// e.g. `zksolc` [supports][zksolc_keccak] keccak256 hash of the metadata as an alternative to CBOR. +/// +/// [zksolc_keccak]: https://matter-labs.github.io/era-compiler-solidity/latest/02-command-line-interface.html#--metadata-hash +// Note: there are missing opportunities here, e.g. Etherscan is able to detect the contracts +// that differ in creation bytecode and/or constructor arguments (for partial match). This is +// less relevant for ZKsync, since there is no concept of creation bytecode there; although +// this may become needed if we will extend the EVM support. +#[derive(Debug, Clone, Copy)] +pub struct ContractIdentifier { + /// Marker of the bytecode of the contract. + pub bytecode_marker: BytecodeMarker, + /// keccak256 hash of the full contract bytecode. + /// Can be used as an identifier of precise contract compilation. + pub bytecode_keccak256: H256, + /// keccak256 hash of the contract bytecode without metadata (e.g. with either + /// CBOR or keccak256 metadata hash being stripped). + /// If no metadata is detected, equal to `bytecode_keccak256`. + pub bytecode_without_metadata_keccak256: H256, + /// Kind of detected metadata. + pub detected_metadata: Option, +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Match { + /// Contracts are identical. + Full, + /// Metadata is different. + Partial, + /// No match. + None, +} + +/// Metadata detected in the contract bytecode. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DetectedMetadata { + /// keccak256 metadata (only for EraVM) + Keccak256, + /// CBOR metadata + Cbor, +} + +/// Possible values for the metadata hashes structure. +/// Details can be found here: https://docs.soliditylang.org/en/latest/metadata.html +/// +/// We're not really interested in the values here, we just want to make sure that we +/// can deserialize the metadata. +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +struct CborMetadata { + #[serde(skip_serializing_if = "Option::is_none")] + ipfs: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + bzzr1: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + bzzr0: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + experimental: Option, + #[serde(skip_serializing_if = "Option::is_none")] + solc: Option>, +} + +impl ContractIdentifier { + pub fn from_bytecode(bytecode_marker: BytecodeMarker, bytecode: &[u8]) -> Self { + // Calculate the hash for bytecode with metadata. + let bytecode_keccak256 = H256(keccak256(bytecode)); + + // Try to detect metadata. + // CBOR takes precedence (since keccak doesn't have direct markers, so it's partially a + // fallback). + let (detected_metadata, bytecode_without_metadata_keccak256) = + if let Some(hash) = Self::detect_cbor_metadata(bytecode_marker, bytecode) { + (Some(DetectedMetadata::Cbor), hash) + } else if let Some(hash) = Self::detect_keccak_metadata(bytecode_marker, bytecode) { + (Some(DetectedMetadata::Keccak256), hash) + } else { + // Fallback + (None, bytecode_keccak256) + }; + + Self { + bytecode_marker, + bytecode_keccak256, + bytecode_without_metadata_keccak256, + detected_metadata, + } + } + + /// Will try to detect keccak256 metadata hash (only for EraVM) + fn detect_keccak_metadata(bytecode_marker: BytecodeMarker, bytecode: &[u8]) -> Option { + // For EraVM, the one option for metadata hash is keccak256 hash of the metadata. + if bytecode_marker == BytecodeMarker::EraVm { + // For metadata, we might have padding: it takes either 32 or 64 bytes depending + // on whether the amount of words in the contract is odd, so we need to check + // if there is padding. + let bytecode_without_metadata = Self::strip_padding(bytecode, 32)?; + let hash = H256(keccak256(bytecode_without_metadata)); + Some(hash) + } else { + None + } + } + + /// Will try to detect CBOR metadata. + fn detect_cbor_metadata(bytecode_marker: BytecodeMarker, bytecode: &[u8]) -> Option { + let length = bytecode.len(); + + // Last two bytes is the length of the metadata in big endian. + if length < 2 { + return None; + } + let metadata_length = + u16::from_be_bytes([bytecode[length - 2], bytecode[length - 1]]) as usize; + // Including size + let full_metadata_length = metadata_length + 2; + + // Get slice for the metadata. + if length < full_metadata_length { + return None; + } + let raw_metadata = &bytecode[length - full_metadata_length..length - 2]; + // Try decoding. We are not interested in the actual value. + let _metadata: CborMetadata = match ciborium::from_reader(raw_metadata) { + Ok(metadata) => metadata, + Err(_) => return None, + }; + + // Strip metadata and calculate hash. + let bytecode_without_metadata = match bytecode_marker { + BytecodeMarker::Evm => { + // On EVM, there is no padding. + &bytecode[..length - full_metadata_length] + } + BytecodeMarker::EraVm => { + // On EraVM, there is padding: + // 1. We must align the metadata length to 32 bytes. + // 2. We may need to add 32 bytes of padding. + let aligned_metadata_length = metadata_length.div_ceil(32) * 32; + Self::strip_padding(bytecode, aligned_metadata_length)? + } + }; + let hash = H256(keccak256(bytecode_without_metadata)); + Some(hash) + } + + /// Adds one word to the metadata length and check if it's a padding word. + /// If it is, strips the padding. + /// Returns `None` if `metadata_length` + padding won't fit into the bytecode. + fn strip_padding(bytecode: &[u8], metadata_length: usize) -> Option<&[u8]> { + const PADDING_WORD: [u8; 32] = [0u8; 32]; + + let length = bytecode.len(); + let metadata_with_padding_length = metadata_length + 32; + if length < metadata_with_padding_length { + return None; + } + if bytecode[length - metadata_with_padding_length..length - metadata_length] == PADDING_WORD + { + // Padding was added, strip it. + Some(&bytecode[..length - metadata_with_padding_length]) + } else { + // Padding wasn't added, strip metadata only. + Some(&bytecode[..length - metadata_length]) + } + } + + /// Checks the kind of match between identifier and other bytecode. + pub fn matches(&self, other: &[u8]) -> Match { + let other_identifier = Self::from_bytecode(self.bytecode_marker, other); + + if self.bytecode_keccak256 == other_identifier.bytecode_keccak256 { + return Match::Full; + } + + // Check if metadata is different. + // Note that here we do not handle "complex" cases, e.g. lack of metadata in one contract + // and presence in another, or different kinds of metadata. This is OK: partial + // match is needed mostly when you cannot reproduce the original metadata, but one always + // can submit the contract with the same metadata kind. + if self.bytecode_without_metadata_keccak256 + == other_identifier.bytecode_without_metadata_keccak256 + { + return Match::Partial; + } + + Match::None + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn eravm_cbor_without_padding() { + // Sample contract with no methods, compiled from the root of monorepo with: + // ./etc/zksolc-bin/v1.5.8/zksolc --solc ./etc/solc-bin/zkVM-0.8.28-1.0.1/solc --metadata-hash ipfs --codegen yul test.sol --bin + // (Use `zkstack contract-verifier init` to download compilers) + let data = hex::decode("0000008003000039000000400030043f0000000100200190000000110000c13d0000000900100198000000190000613d000000000101043b0000000a011001970000000b0010009c000000190000c13d0000000001000416000000000001004b000000190000c13d000000000100041a000000800010043f0000000c010000410000001c0001042e0000000001000416000000000001004b000000190000c13d00000020010000390000010000100443000001200000044300000008010000410000001c0001042e00000000010000190000001d000104300000001b000004320000001c0001042e0000001d0001043000000000000000000000000000000000000000020000000000000000000000000000004000000100000000000000000000000000000000000000000000000000fffffffc000000000000000000000000ffffffff000000000000000000000000000000000000000000000000000000006d4ce63c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000008000000000000000000000000000000000000000000000000000000000a16469706673582212208acf048570dcc1c3ff41bf8f20376049a42ae8a471f2b2ae8c14d8b356d86d79002a").unwrap(); + let bytecode_keccak256 = H256(keccak256(&data)); + let full_metadata_len = 64; // (CBOR metadata + len bytes) + let bytecode_without_metadata_keccak256 = + H256(keccak256(&data[..data.len() - full_metadata_len])); + + let identifier = ContractIdentifier::from_bytecode(BytecodeMarker::EraVm, &data); + assert_eq!( + identifier.bytecode_keccak256, bytecode_keccak256, + "Incorrect bytecode hash" + ); + assert_eq!( + identifier.detected_metadata, + Some(DetectedMetadata::Cbor), + "Incorrect detected metadata" + ); + assert_eq!( + identifier.bytecode_without_metadata_keccak256, bytecode_without_metadata_keccak256, + "Incorrect bytecode without metadata hash" + ); + } + + #[test] + fn eravm_cbor_with_padding() { + // Same as `eravm_cbor_without_padding` but now bytecode has padding. + let data = hex::decode("00000001002001900000000c0000613d0000008001000039000000400010043f0000000001000416000000000001004b0000000c0000c13d00000020010000390000010000100443000001200000044300000005010000410000000f0001042e000000000100001900000010000104300000000e000004320000000f0001042e0000001000010430000000000000000000000000000000000000000000000000000000020000000000000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a1646970667358221220d5be4da510b089bb58fa6c65f0a387eef966bcf48671a24fb2b1bc7190842978002a").unwrap(); + let bytecode_keccak256 = H256(keccak256(&data)); + let full_metadata_len = 64 + 32; // (CBOR metadata + len bytes + padding) + let bytecode_without_metadata_keccak256 = + H256(keccak256(&data[..data.len() - full_metadata_len])); + + let identifier = ContractIdentifier::from_bytecode(BytecodeMarker::EraVm, &data); + assert_eq!( + identifier.bytecode_keccak256, bytecode_keccak256, + "Incorrect bytecode hash" + ); + assert_eq!( + identifier.detected_metadata, + Some(DetectedMetadata::Cbor), + "Incorrect detected metadata" + ); + assert_eq!( + identifier.bytecode_without_metadata_keccak256, bytecode_without_metadata_keccak256, + "Incorrect bytecode without metadata hash" + ); + } + + #[test] + fn eravm_keccak_without_padding() { + // Sample contract with no methods, compiled from the root of monorepo with: + // ./etc/zksolc-bin/v1.5.8/zksolc --solc ./etc/solc-bin/zkVM-0.8.28-1.0.1/solc --metadata-hash keccak256 --codegen yul test.sol --bin + // (Use `zkstack contract-verifier init` to download compilers) + let data = hex::decode("00000001002001900000000c0000613d0000008001000039000000400010043f0000000001000416000000000001004b0000000c0000c13d00000020010000390000010000100443000001200000044300000005010000410000000f0001042e000000000100001900000010000104300000000e000004320000000f0001042e000000100001043000000000000000000000000000000000000000000000000000000002000000000000000000000000000000400000010000000000000000000a00e4a5f19bb139176aa501024c7032404c065bc0012897fefd9ebc7e9a7677").unwrap(); + let bytecode_keccak256 = H256(keccak256(&data)); + let full_metadata_len = 32; // (keccak only) + let bytecode_without_metadata_keccak256 = + H256(keccak256(&data[..data.len() - full_metadata_len])); + + let identifier = ContractIdentifier::from_bytecode(BytecodeMarker::EraVm, &data); + assert_eq!( + identifier.bytecode_keccak256, bytecode_keccak256, + "Incorrect bytecode hash" + ); + assert_eq!( + identifier.detected_metadata, + Some(DetectedMetadata::Keccak256), + "Incorrect detected metadata" + ); + assert_eq!( + identifier.bytecode_without_metadata_keccak256, bytecode_without_metadata_keccak256, + "Incorrect bytecode without metadata hash" + ); + } + + #[test] + fn eravm_keccak_with_padding() { + // Same as `eravm_keccak_without_padding`, but now bytecode has padding. + let data = hex::decode("0000008003000039000000400030043f0000000100200190000000110000c13d0000000900100198000000190000613d000000000101043b0000000a011001970000000b0010009c000000190000c13d0000000001000416000000000001004b000000190000c13d000000000100041a000000800010043f0000000c010000410000001c0001042e0000000001000416000000000001004b000000190000c13d00000020010000390000010000100443000001200000044300000008010000410000001c0001042e00000000010000190000001d000104300000001b000004320000001c0001042e0000001d0001043000000000000000000000000000000000000000020000000000000000000000000000004000000100000000000000000000000000000000000000000000000000fffffffc000000000000000000000000ffffffff000000000000000000000000000000000000000000000000000000006d4ce63c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000080000000000000000000000000000000000000000000000000000000000000000000000000000000009b1f0a6172ae84051eca37db231c0fa6249349f4ddaf86a87474a587c19d946d").unwrap(); + let bytecode_keccak256 = H256(keccak256(&data)); + let full_metadata_len = 64; // (keccak + padding) + let bytecode_without_metadata_keccak256 = + H256(keccak256(&data[..data.len() - full_metadata_len])); + + let identifier = ContractIdentifier::from_bytecode(BytecodeMarker::EraVm, &data); + assert_eq!( + identifier.bytecode_keccak256, bytecode_keccak256, + "Incorrect bytecode hash" + ); + assert_eq!( + identifier.detected_metadata, + Some(DetectedMetadata::Keccak256), + "Incorrect detected metadata" + ); + assert_eq!( + identifier.bytecode_without_metadata_keccak256, bytecode_without_metadata_keccak256, + "Incorrect bytecode without metadata hash" + ); + } + + #[test] + fn eravm_too_short_bytecode() { + // Random short bytecode + let data = hex::decode("0000008003000039000000400030043f0000000100200190000000110000c13d") + .unwrap(); + let bytecode_keccak256 = H256(keccak256(&data)); + + let identifier = ContractIdentifier::from_bytecode(BytecodeMarker::EraVm, &data); + assert_eq!( + identifier.bytecode_keccak256, bytecode_keccak256, + "Incorrect bytecode hash" + ); + assert_eq!( + identifier.detected_metadata, None, + "Incorrect detected metadata" + ); + // When no metadata is detected, `bytecode_without_metadata_keccak256` is equal to + // `bytecode_keccak256`. + assert_eq!( + identifier.bytecode_without_metadata_keccak256, bytecode_keccak256, + "Incorrect bytecode without metadata hash" + ); + } + + #[test] + fn evm_none() { + // Sample contract with no methods, compiled from the root of monorepo with: + // ./etc/solc-bin/0.8.28/solc test.sol --bin --no-cbor-metadata + // (Use `zkstack contract-verifier init` to download compilers) + let data = hex::decode("6080604052348015600e575f5ffd5b50607980601a5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c80636d4ce63c14602a575b5f5ffd5b60306044565b604051603b91906062565b60405180910390f35b5f5f54905090565b5f819050919050565b605c81604c565b82525050565b5f60208201905060735f8301846055565b9291505056").unwrap(); + let bytecode_keccak256 = H256(keccak256(&data)); + + let identifier = ContractIdentifier::from_bytecode(BytecodeMarker::Evm, &data); + assert_eq!( + identifier.bytecode_keccak256, bytecode_keccak256, + "Incorrect bytecode hash" + ); + assert_eq!( + identifier.detected_metadata, None, + "Incorrect detected metadata" + ); + // When no metadata is detected, `bytecode_without_metadata_keccak256` is equal to + // `bytecode_keccak256`. + assert_eq!( + identifier.bytecode_without_metadata_keccak256, bytecode_keccak256, + "Incorrect bytecode without metadata hash" + ); + } + + #[test] + fn evm_cbor() { + // ./etc/solc-bin/0.8.28/solc test.sol --bin --metadata-hash ipfs + let ipfs_bytecode = "6080604052348015600e575f5ffd5b5060af80601a5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c80636d4ce63c14602a575b5f5ffd5b60306044565b604051603b91906062565b60405180910390f35b5f5f54905090565b5f819050919050565b605c81604c565b82525050565b5f60208201905060735f8301846055565b9291505056fea2646970667358221220bca846db362b62d2eb9891565b12433410e0f6a634657d2c7d1e7469447e8ab564736f6c634300081c0033"; + // ./etc/solc-bin/0.8.28/solc test.sol --bin --metadata-hash none + // Note that cbor will still be included but will only have solc version. + let none_bytecode = "6080604052348015600e575f5ffd5b50608680601a5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c80636d4ce63c14602a575b5f5ffd5b60306044565b604051603b91906062565b60405180910390f35b5f5f54905090565b5f819050919050565b605c81604c565b82525050565b5f60208201905060735f8301846055565b9291505056fea164736f6c634300081c000a"; + // ./etc/solc-bin/0.8.28/solc test.sol --bin --metadata-hash swarm + let swarm_bytecode = "6080604052348015600e575f5ffd5b5060ae80601a5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c80636d4ce63c14602a575b5f5ffd5b60306044565b604051603b91906062565b60405180910390f35b5f5f54905090565b5f819050919050565b605c81604c565b82525050565b5f60208201905060735f8301846055565b9291505056fea265627a7a72315820c0def30c57166e97d6a58290213f3b0d1f83532e7a0371c8e2b6dba826bae46164736f6c634300081c0032"; + + // Different variations of the same contract, compiled with different metadata options. + // Tuples of (label, bytecode, size of metadata (including length)). + // Size of metadata can be found using https://playground.sourcify.dev/ + let test_vector = [ + ("ipfs", ipfs_bytecode, 51usize + 2), + ("none", none_bytecode, 10 + 2), + ("swarm", swarm_bytecode, 50 + 2), + ]; + + for (label, bytecode, full_metadata_len) in test_vector { + let data = hex::decode(bytecode).unwrap(); + let bytecode_keccak256 = H256(keccak256(&data)); + let bytecode_without_metadata_keccak256 = + H256(keccak256(&data[..data.len() - full_metadata_len])); + + let identifier = ContractIdentifier::from_bytecode(BytecodeMarker::Evm, &data); + assert_eq!( + identifier.bytecode_keccak256, bytecode_keccak256, + "{label}: Incorrect bytecode hash" + ); + assert_eq!( + identifier.detected_metadata, + Some(DetectedMetadata::Cbor), + "{label}: Incorrect detected metadata" + ); + assert_eq!( + identifier.bytecode_without_metadata_keccak256, bytecode_without_metadata_keccak256, + "{label}: Incorrect bytecode without metadata hash" + ); + } + } +} diff --git a/core/lib/types/src/contract_verification/mod.rs b/core/lib/types/src/contract_verification/mod.rs new file mode 100644 index 000000000000..7f8686941edb --- /dev/null +++ b/core/lib/types/src/contract_verification/mod.rs @@ -0,0 +1,2 @@ +pub mod api; +pub mod contract_identifier; diff --git a/core/lib/types/src/lib.rs b/core/lib/types/src/lib.rs index 8ec98ec0571e..606de9b9e798 100644 --- a/core/lib/types/src/lib.rs +++ b/core/lib/types/src/lib.rs @@ -32,7 +32,7 @@ pub mod aggregated_operations; pub mod blob; pub mod block; pub mod commitment; -pub mod contract_verification_api; +pub mod contract_verification; pub mod debug_flat_call; pub mod fee; pub mod fee_model; diff --git a/core/lib/utils/src/env.rs b/core/lib/utils/src/env.rs index 8f4aa1da9400..0da0ddbc9f70 100644 --- a/core/lib/utils/src/env.rs +++ b/core/lib/utils/src/env.rs @@ -11,11 +11,9 @@ static WORKSPACE: OnceCell> = OnceCell::new(); /// Represents Cargo workspaces available in the repository. #[derive(Debug, Clone, Copy)] pub enum Workspace<'a> { - /// Workspace was not found. - /// Assumes that the code is running in a binary. - /// Will use the current directory as a fallback. - None, /// Root folder. + Root, + /// `core` folder. Core(&'a Path), /// `prover` folder. Prover(&'a Path), @@ -42,21 +40,30 @@ impl Workspace<'static> { result.ok() }) .as_deref(); - path.map_or(Self::None, Self::from) + path.map_or(Self::Root, Self::from) } } impl<'a> Workspace<'a> { + const CORE_DIRECTORY_NAME: &'static str = "core"; const PROVER_DIRECTORY_NAME: &'static str = "prover"; const ZKSTACK_CLI_DIRECTORY_NAME: &'static str = "zkstack_cli"; - /// Returns the path of the core workspace. - /// For `Workspace::None`, considers the current directory to represent core workspace. + /// Returns the path of the repository root. + pub fn root(self) -> PathBuf { + match self { + Self::Root => PathBuf::from("."), + Self::Core(path) | Self::Prover(path) | Self::ZkStackCli(path) => { + path.parent().unwrap().into() + } + } + } + + /// Returns the path of the `core` workspace. pub fn core(self) -> PathBuf { match self { - Self::None => PathBuf::from("."), Self::Core(path) => path.into(), - Self::Prover(path) | Self::ZkStackCli(path) => path.parent().unwrap().into(), + _ => self.root().join(Self::CORE_DIRECTORY_NAME), } } @@ -64,7 +71,7 @@ impl<'a> Workspace<'a> { pub fn prover(self) -> PathBuf { match self { Self::Prover(path) => path.into(), - _ => self.core().join(Self::PROVER_DIRECTORY_NAME), + _ => self.root().join(Self::PROVER_DIRECTORY_NAME), } } @@ -72,7 +79,7 @@ impl<'a> Workspace<'a> { pub fn zkstack_cli(self) -> PathBuf { match self { Self::ZkStackCli(path) => path.into(), - _ => self.core().join(Self::ZKSTACK_CLI_DIRECTORY_NAME), + _ => self.root().join(Self::ZKSTACK_CLI_DIRECTORY_NAME), } } } @@ -83,8 +90,10 @@ impl<'a> From<&'a Path> for Workspace<'a> { Self::Prover(path) } else if path.ends_with(Self::ZKSTACK_CLI_DIRECTORY_NAME) { Self::ZkStackCli(path) - } else { + } else if path.ends_with(Self::CORE_DIRECTORY_NAME) { Self::Core(path) + } else { + Self::Root } } } @@ -150,7 +159,6 @@ mod tests { let _pwd_protector = PwdProtector::new(); // Core. - let workspace = Workspace::locate(); assert_matches!(workspace, Workspace::Core(_)); let core_path = workspace.core(); diff --git a/core/lib/vm_executor/src/batch/factory.rs b/core/lib/vm_executor/src/batch/factory.rs index 59b610426669..5e375d1f3062 100644 --- a/core/lib/vm_executor/src/batch/factory.rs +++ b/core/lib/vm_executor/src/batch/factory.rs @@ -8,8 +8,8 @@ use zksync_multivm::{ executor::{BatchExecutor, BatchExecutorFactory}, pubdata::PubdataBuilder, storage::{ReadStorage, StoragePtr, StorageView, StorageViewStats}, - utils::DivergenceHandler, - BatchTransactionExecutionResult, BytecodeCompressionError, CompressedBytecodeInfo, + utils::{DivergenceHandler, ShadowMut}, + BatchTransactionExecutionResult, BytecodeCompressionError, Call, CompressedBytecodeInfo, ExecutionResult, FinishedL1Batch, Halt, L1BatchEnv, L2BlockEnv, SystemEnv, VmFactory, VmInterface, VmInterfaceHistoryEnabled, }, @@ -28,6 +28,23 @@ use super::{ }; use crate::shared::{InteractionType, Sealed, STORAGE_METRICS}; +#[doc(hidden)] +pub trait CallTracingTracer: vm_fast::interface::Tracer + Default { + fn into_traces(self) -> Vec; +} + +impl CallTracingTracer for () { + fn into_traces(self) -> Vec { + vec![] + } +} + +impl CallTracingTracer for vm_fast::CallTracer { + fn into_traces(self) -> Vec { + self.into_result() + } +} + /// Encapsulates a tracer used during batch processing. Currently supported tracers are `()` (no-op) and [`TraceCalls`]. /// /// All members of this trait are implementation details. @@ -37,7 +54,7 @@ pub trait BatchTracer: fmt::Debug + 'static + Send + Sealed { const TRACE_CALLS: bool; /// Tracer for the fast VM. #[doc(hidden)] - type Fast: vm_fast::interface::Tracer + Default; + type Fast: CallTracingTracer; } impl Sealed for () {} @@ -56,7 +73,7 @@ impl Sealed for TraceCalls {} impl BatchTracer for TraceCalls { const TRACE_CALLS: bool = true; - type Fast = (); // TODO: change once call tracing is implemented in fast VM + type Fast = vm_fast::CallTracer; } /// The default implementation of [`BatchExecutorFactory`]. @@ -213,13 +230,14 @@ impl BatchVm { tx: Transaction, with_compression: bool, ) -> BatchTransactionExecutionResult { - let call_tracer_result = Arc::new(OnceCell::default()); + let legacy_tracer_result = Arc::new(OnceCell::default()); let legacy_tracer = if Tr::TRACE_CALLS { - vec![CallTracer::new(call_tracer_result.clone()).into_tracer_pointer()] + vec![CallTracer::new(legacy_tracer_result.clone()).into_tracer_pointer()] } else { vec![] }; let mut legacy_tracer = legacy_tracer.into(); + let mut fast_traces = vec![]; let (compression_result, tx_result) = match self { Self::Legacy(vm) => vm.inspect_transaction_with_bytecode_compression( @@ -228,16 +246,34 @@ impl BatchVm { with_compression, ), Self::Fast(vm) => { - let mut tracer = (legacy_tracer.into(), Default::default()); - vm.inspect_transaction_with_bytecode_compression(&mut tracer, tx, with_compression) + let mut tracer = (legacy_tracer.into(), (Tr::Fast::default(), ())); + let res = vm.inspect_transaction_with_bytecode_compression( + &mut tracer, + tx, + with_compression, + ); + let (_, (call_tracer, _)) = tracer; + fast_traces = call_tracer.into_traces(); + res } }; let compressed_bytecodes = compression_result.map(Cow::into_owned); - let call_traces = Arc::try_unwrap(call_tracer_result) + let legacy_traces = Arc::try_unwrap(legacy_tracer_result) .expect("failed extracting call traces") .take() .unwrap_or_default(); + let call_traces = match self { + Self::Legacy(_) => legacy_traces, + Self::Fast(FastVmInstance::Fast(_)) => fast_traces, + Self::Fast(FastVmInstance::Shadowed(vm)) => { + vm.get_custom_mut("call_traces", |r| match r { + ShadowMut::Main(_) => legacy_traces.as_slice(), + ShadowMut::Shadow(_) => fast_traces.as_slice(), + }); + fast_traces + } + }; BatchTransactionExecutionResult { tx_result: Box::new(tx_result), diff --git a/core/lib/vm_interface/src/utils/shadow.rs b/core/lib/vm_interface/src/utils/shadow.rs index d6a6d16c77a0..e4a7aa51f78c 100644 --- a/core/lib/vm_interface/src/utils/shadow.rs +++ b/core/lib/vm_interface/src/utils/shadow.rs @@ -7,16 +7,19 @@ use std::{ sync::Arc, }; -use zksync_types::{StorageKey, StorageLog, StorageLogWithPreviousValue, Transaction}; +use zksync_types::{ + Address, StorageKey, StorageLog, StorageLogWithPreviousValue, Transaction, U256, +}; use super::dump::{DumpingVm, VmDump}; use crate::{ pubdata::PubdataBuilder, storage::{ReadStorage, StoragePtr, StorageView}, tracer::{ValidationError, ValidationTraces}, - BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, InspectExecutionMode, - L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionResultAndLogs, VmFactory, - VmInterface, VmInterfaceHistoryEnabled, VmTrackingContracts, + BytecodeCompressionResult, Call, CallType, CurrentExecutionState, FinishedL1Batch, + InspectExecutionMode, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, + VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, + VmTrackingContracts, }; /// Handler for VM divergences. @@ -233,6 +236,64 @@ impl CheckDivergence for Result { } } +/// `PartialEq` for `Call` doesn't compare gas-related fields. Here, we do compare them. +#[derive(Debug, PartialEq)] +struct StrictCall<'a> { + r#type: CallType, + from: Address, + to: Address, + // `gas` / `parent_gas` differ between fast VM and legacy VM during validation + gas_used: u64, + value: U256, + input: &'a [u8], + output: &'a [u8], + error: Option<&'a str>, + revert_reason: Option<&'a str>, +} + +impl<'a> StrictCall<'a> { + fn flatten(calls: &'a [Call]) -> Vec { + let mut flattened = Vec::new(); + Self::flatten_inner(&mut flattened, calls); + flattened + } + + fn flatten_inner(flattened: &mut Vec, calls: &'a [Call]) { + // Depth-first, parents-before-children traversal. + for call in calls { + flattened.push(Self { + r#type: call.r#type, + from: call.from, + to: call.to, + gas_used: call.gas_used, + value: call.value, + input: &call.input, + output: &call.output, + error: call.error.as_deref(), + revert_reason: call.revert_reason.as_deref(), + }); + Self::flatten_inner(flattened, &call.calls); + } + } +} + +impl CheckDivergence for [Call] { + fn check_divergence(&self, other: &Self) -> DivergenceErrors { + let this = StrictCall::flatten(self); + let other = StrictCall::flatten(other); + let mut errors = DivergenceErrors::new(); + + errors.check_match("call_traces", &this, &other); + errors + } +} + +impl CheckDivergence for &T { + fn check_divergence(&self, other: &Self) -> DivergenceErrors { + (**self).check_divergence(*other) + } +} + /// Shadowed VM that executes 2 VMs for each operation and compares their outputs. /// /// If a divergence is detected, the VM state is dumped using [a pluggable handler](Self::set_dump_handler()), @@ -526,7 +587,8 @@ impl DivergenceErrors { } } - fn extend(&mut self, from: Self) { + /// Extends this instance from another set of errors. + pub fn extend(&mut self, from: Self) { self.divergences.extend(from.divergences); } diff --git a/core/node/api_server/src/execution_sandbox/mod.rs b/core/node/api_server/src/execution_sandbox/mod.rs index bcba200f5ebc..78bc85de9f22 100644 --- a/core/node/api_server/src/execution_sandbox/mod.rs +++ b/core/node/api_server/src/execution_sandbox/mod.rs @@ -274,7 +274,7 @@ impl BlockStartInfo { #[derive(Debug, thiserror::Error)] pub enum BlockArgsError { - #[error("Block is pruned; first retained block is {0}")] + #[error("Block is not available, either it was pruned or the node was started from a snapshot created later than this block; first retained block is {0}")] Pruned(L2BlockNumber), #[error("Block is missing, but can appear in the future")] Missing, diff --git a/core/node/api_server/src/web3/namespaces/debug.rs b/core/node/api_server/src/web3/namespaces/debug.rs index 98af15032008..a70367a858fb 100644 --- a/core/node/api_server/src/web3/namespaces/debug.rs +++ b/core/node/api_server/src/web3/namespaces/debug.rs @@ -54,6 +54,7 @@ impl DebugNamespace { } } } + pub(crate) fn map_default_call( call: Call, only_top_call: bool, @@ -173,6 +174,11 @@ impl DebugNamespace { } let mut connection = self.state.acquire_connection().await?; + self.state + .start_info + .ensure_not_pruned(block_id, &mut connection) + .await?; + let block_number = self.state.resolve_block(&mut connection, block_id).await?; // let block_hash = block_hash self.state. self.current_method() @@ -251,6 +257,11 @@ impl DebugNamespace { let options = options.unwrap_or_default(); let mut connection = self.state.acquire_connection().await?; + self.state + .start_info + .ensure_not_pruned(block_id, &mut connection) + .await?; + let block_args = self .state .resolve_block_args(&mut connection, block_id) diff --git a/core/node/api_server/src/web3/namespaces/zks.rs b/core/node/api_server/src/web3/namespaces/zks.rs index b272f7c443e9..9f7c5662a631 100644 --- a/core/node/api_server/src/web3/namespaces/zks.rs +++ b/core/node/api_server/src/web3/namespaces/zks.rs @@ -677,9 +677,7 @@ impl ZksNamespace { Ok(self .state .tx_sender - .0 - .batch_fee_input_provider - .get_batch_fee_input() + .scaled_batch_fee_input() .await? .into_pubdata_independent()) } diff --git a/core/node/api_server/src/web3/state.rs b/core/node/api_server/src/web3/state.rs index 97ffd933c801..1319c866968c 100644 --- a/core/node/api_server/src/web3/state.rs +++ b/core/node/api_server/src/web3/state.rs @@ -241,8 +241,9 @@ impl BridgeAddressesHandle { self.0.write().await.l1_shared_default_bridge = Some(l1_shared_bridge); } - pub async fn update_l2_shared_bridge(&self, l2_shared_bridge: Address) { + pub async fn update_l2_bridges(&self, l2_shared_bridge: Address) { self.0.write().await.l2_shared_default_bridge = Some(l2_shared_bridge); + self.0.write().await.l2_erc20_default_bridge = Some(l2_shared_bridge); } pub async fn read(&self) -> api::BridgeAddresses { diff --git a/core/node/consensus/src/config.rs b/core/node/consensus/src/config.rs index 2cb6045151bd..733500998a30 100644 --- a/core/node/consensus/src/config.rs +++ b/core/node/consensus/src/config.rs @@ -42,7 +42,6 @@ pub(super) struct GenesisSpec { pub(super) chain_id: validator::ChainId, pub(super) protocol_version: validator::ProtocolVersion, pub(super) validators: validator::Committee, - pub(super) attesters: Option, pub(super) leader_selection: validator::LeaderSelectionMode, pub(super) registry_address: Option, pub(super) seed_peers: BTreeMap, @@ -54,7 +53,6 @@ impl GenesisSpec { chain_id: cfg.genesis.chain_id, protocol_version: cfg.genesis.protocol_version, validators: cfg.genesis.validators.clone(), - attesters: cfg.genesis.attesters.clone(), leader_selection: cfg.genesis.leader_selection.clone(), registry_address: cfg.registry_address, seed_peers: cfg.seed_peers.clone(), @@ -75,19 +73,6 @@ impl GenesisSpec { .collect::>() .context("validators")?; - let attesters: Vec<_> = x - .attesters - .iter() - .enumerate() - .map(|(i, v)| { - Ok(attester::WeightedAttester { - key: Text::new(&v.key.0).decode().context("key").context(i)?, - weight: v.weight, - }) - }) - .collect::>() - .context("attesters")?; - Ok(Self { chain_id: validator::ChainId(x.chain_id.as_u64()), protocol_version: validator::ProtocolVersion(x.protocol_version.0), @@ -95,11 +80,6 @@ impl GenesisSpec { Text::new(&x.leader.0).decode().context("leader")?, ), validators: validator::Committee::new(validators).context("validators")?, - attesters: if attesters.is_empty() { - None - } else { - Some(attester::Committee::new(attesters).context("attesters")?) - }, registry_address: x.registry_address, seed_peers: x .seed_peers diff --git a/core/node/consensus/src/en.rs b/core/node/consensus/src/en.rs index 2bddc3280362..ffb580ce1284 100644 --- a/core/node/consensus/src/en.rs +++ b/core/node/consensus/src/en.rs @@ -208,7 +208,7 @@ impl EN { attestation: Arc, ) -> ctx::Result<()> { const POLL_INTERVAL: time::Duration = time::Duration::seconds(5); - let registry = registry::Registry::new(cfg.genesis.clone(), self.pool.clone()).await; + let registry = registry::Registry::new(self.pool.clone()).await; let mut next = attester::BatchNumber(0); loop { let status = loop { diff --git a/core/node/consensus/src/mn.rs b/core/node/consensus/src/mn.rs index a392acfbe5f0..028a635398c6 100644 --- a/core/node/consensus/src/mn.rs +++ b/core/node/consensus/src/mn.rs @@ -118,7 +118,7 @@ async fn run_attestation_controller( attestation: Arc, ) -> ctx::Result<()> { const POLL_INTERVAL: time::Duration = time::Duration::seconds(5); - let registry = registry::Registry::new(cfg.genesis, pool.clone()).await; + let registry = registry::Registry::new(pool.clone()).await; let registry_addr = cfg.registry_address.map(registry::Address::new); let mut next = attester::BatchNumber(0); loop { diff --git a/core/node/consensus/src/registry/mod.rs b/core/node/consensus/src/registry/mod.rs index 74da41309573..235389acda0e 100644 --- a/core/node/consensus/src/registry/mod.rs +++ b/core/node/consensus/src/registry/mod.rs @@ -1,7 +1,7 @@ use anyhow::Context as _; use zksync_concurrency::{ctx, error::Wrap as _}; use zksync_consensus_crypto::ByteFmt; -use zksync_consensus_roles::{attester, validator}; +use zksync_consensus_roles::attester; use crate::{storage::ConnectionPool, vm::VM}; @@ -30,22 +30,20 @@ pub type Address = crate::abi::Address; #[derive(Debug)] pub(crate) struct Registry { contract: abi::ConsensusRegistry, - genesis: validator::Genesis, vm: VM, } impl Registry { - pub async fn new(genesis: validator::Genesis, pool: ConnectionPool) -> Self { + pub async fn new(pool: ConnectionPool) -> Self { Self { contract: abi::ConsensusRegistry::load(), - genesis, vm: VM::new(pool).await, } } /// Attester committee for the given batch. /// It reads committee from the contract. - /// Falls back to committee specified in the genesis. + /// Falls back to empty committee. pub async fn attester_committee_for( &self, ctx: &ctx::Ctx, @@ -57,7 +55,7 @@ impl Registry { return Ok(None); }; let Some(address) = address else { - return Ok(self.genesis.attesters.clone()); + return Ok(None); }; let raw = self .vm diff --git a/core/node/consensus/src/registry/tests.rs b/core/node/consensus/src/registry/tests.rs index 15329077a651..736b6c9b3ac7 100644 --- a/core/node/consensus/src/registry/tests.rs +++ b/core/node/consensus/src/registry/tests.rs @@ -1,6 +1,6 @@ use rand::Rng as _; use zksync_concurrency::{ctx, scope, time}; -use zksync_consensus_roles::{attester, validator::testonly::Setup}; +use zksync_consensus_roles::attester; use zksync_test_contracts::Account; use zksync_types::ProtocolVersionId; @@ -26,21 +26,20 @@ async fn test_attester_committee() { zksync_concurrency::testonly::abort_on_panic(); let ctx = &ctx::test_root(&ctx::RealClock); let rng = &mut ctx.rng(); - let setup = Setup::new(rng, 10); let account = &mut Account::random(); let to_fund = &[account.address]; scope::run!(ctx, |ctx, s| async { let pool = ConnectionPool::test(false, ProtocolVersionId::latest()).await; - let registry = Registry::new(setup.genesis.clone(), pool.clone()).await; + let registry = Registry::new(pool.clone()).await; // If the registry contract address is not specified, - // then the committee from genesis should be returned. + // then an empty committee should be returned. let got = registry .attester_committee_for(ctx, None, attester::BatchNumber(10)) .await .unwrap(); - assert_eq!(setup.genesis.attesters, got); + assert!(got.is_none()); let (mut node, runner) = crate::testonly::StateKeeper::new(ctx, pool.clone()).await?; s.spawn_bg(runner.run_real(ctx, to_fund)); diff --git a/core/node/consensus/src/storage/connection.rs b/core/node/consensus/src/storage/connection.rs index 6ec5794e968d..08fa7996bdc1 100644 --- a/core/node/consensus/src/storage/connection.rs +++ b/core/node/consensus/src/storage/connection.rs @@ -277,7 +277,6 @@ impl<'a> Connection<'a> { first_block: txn.next_block(ctx).await.context("next_block()")?, protocol_version: spec.protocol_version, validators: spec.validators.clone(), - attesters: spec.attesters.clone(), leader_selection: spec.leader_selection.clone(), } .with_hash(), diff --git a/core/node/consensus/src/storage/testonly.rs b/core/node/consensus/src/storage/testonly.rs index 295ae4fc1790..858bca542c33 100644 --- a/core/node/consensus/src/storage/testonly.rs +++ b/core/node/consensus/src/storage/testonly.rs @@ -16,6 +16,7 @@ use crate::registry; impl Connection<'_> { /// Wrapper for `consensus_dal().batch_of_block()`. + #[allow(dead_code)] pub async fn batch_of_block( &mut self, ctx: &ctx::Ctx, @@ -27,6 +28,7 @@ impl Connection<'_> { } /// Wrapper for `consensus_dal().last_batch_certificate_number()`. + #[allow(dead_code)] pub async fn last_batch_certificate_number( &mut self, ctx: &ctx::Ctx, @@ -37,6 +39,7 @@ impl Connection<'_> { } /// Wrapper for `consensus_dal().batch_certificate()`. + #[allow(dead_code)] pub async fn batch_certificate( &mut self, ctx: &ctx::Ctx, @@ -187,6 +190,7 @@ impl ConnectionPool { Ok(blocks) } + #[allow(dead_code)] pub async fn wait_for_batch_certificates_and_verify( &self, ctx: &ctx::Ctx, @@ -217,7 +221,7 @@ impl ConnectionPool { .await .wrap("batch_of_block()")? .context("batch of first_block is missing")?; - let registry = registry::Registry::new(cfg.genesis.clone(), self.clone()).await; + let registry = registry::Registry::new(self.clone()).await; for i in first.0..want_last.0 { let i = attester::BatchNumber(i); let cert = conn diff --git a/core/node/consensus/src/tests/attestation.rs b/core/node/consensus/src/tests/attestation.rs index 6f24fbe65b4c..8e20474f453c 100644 --- a/core/node/consensus/src/tests/attestation.rs +++ b/core/node/consensus/src/tests/attestation.rs @@ -151,7 +151,7 @@ async fn test_multiple_attesters(version: ProtocolVersionId) { tracing::info!("deploy registry with 1 attester"); let attesters: Vec<_> = setup.genesis.attesters.as_ref().unwrap().iter().collect(); - let registry = Registry::new(setup.genesis.clone(), validator_pool.clone()).await; + let registry = Registry::new(validator_pool.clone()).await; let (registry_addr, tx) = registry.deploy(account); cfgs[0] .config diff --git a/core/node/consensus/src/tests/mod.rs b/core/node/consensus/src/tests/mod.rs index c7697ba8480e..c685fdd3223d 100644 --- a/core/node/consensus/src/tests/mod.rs +++ b/core/node/consensus/src/tests/mod.rs @@ -22,7 +22,10 @@ use crate::{ testonly, }; -mod attestation; +// NOTE: These tests are disabled since we are going to remove L1 batches. Most likely +// we will remove all the attester related code as well, but keeping this until +// we are sure. +//mod attestation; const VERSIONS: [ProtocolVersionId; 2] = [ProtocolVersionId::latest(), ProtocolVersionId::next()]; const FROM_SNAPSHOT: [bool; 2] = [true, false]; diff --git a/core/node/contract_verification_server/src/api_impl.rs b/core/node/contract_verification_server/src/api_impl.rs index b0336fd284b6..3e21c2f2cba8 100644 --- a/core/node/contract_verification_server/src/api_impl.rs +++ b/core/node/contract_verification_server/src/api_impl.rs @@ -7,11 +7,15 @@ use axum::{ response::{IntoResponse, Response}, Json, }; -use zksync_dal::{CoreDal, DalError}; +use zksync_dal::{contract_verification_dal::ContractVerificationDal, CoreDal, DalError}; use zksync_types::{ - bytecode::BytecodeMarker, - contract_verification_api::{ - CompilerVersions, VerificationIncomingRequest, VerificationInfo, VerificationRequestStatus, + bytecode::{trim_bytecode, BytecodeHash, BytecodeMarker}, + contract_verification::{ + api::{ + CompilerVersions, VerificationIncomingRequest, VerificationInfo, VerificationProblem, + VerificationRequestStatus, + }, + contract_identifier::ContractIdentifier, }, Address, }; @@ -220,15 +224,73 @@ impl RestApi { address: Path
, ) -> ApiResult { let method_latency = METRICS.call[&"contract_verification_info"].start(); - let info = self_ + let mut conn = self_ .replica_connection_pool .connection_tagged("api") - .await? - .contract_verification_dal() - .get_contract_verification_info(*address) - .await? - .ok_or(ApiError::VerificationInfoNotFound)?; + .await?; + let mut dal = conn.contract_verification_dal(); + + let info = if let Some(info) = dal.get_contract_verification_info(*address).await? { + info + } else if let Some(partial_match) = + get_partial_match_verification_info(&mut dal, *address).await? + { + partial_match + } else { + return Err(ApiError::VerificationInfoNotFound); + }; method_latency.observe(); Ok(Json(info)) } } + +/// Tries to do a lookup for partial match verification info. +/// Should be called only if a perfect match is not found. +async fn get_partial_match_verification_info( + dal: &mut ContractVerificationDal<'_, '_>, + address: Address, +) -> anyhow::Result> { + let Some(deployed_contract) = dal.get_contract_info_for_verification(address).await? else { + return Ok(None); + }; + + let bytecode_hash = + BytecodeHash::try_from(deployed_contract.bytecode_hash).context("Invalid bytecode hash")?; + let deployed_bytecode = trim_bytecode(bytecode_hash, &deployed_contract.bytecode) + .context("Invalid deployed bytecode")?; + + let identifier = ContractIdentifier::from_bytecode(bytecode_hash.marker(), deployed_bytecode); + let Some((mut info, fetched_keccak256, fetched_keccak256_without_metadata)) = dal + .get_partial_match_verification_info( + identifier.bytecode_keccak256, + identifier.bytecode_without_metadata_keccak256, + ) + .await? + else { + return Ok(None); + }; + + if identifier.bytecode_keccak256 != fetched_keccak256 { + // Sanity check + let has_metadata = identifier.detected_metadata.is_some(); + let hashes_without_metadata_match = + identifier.bytecode_without_metadata_keccak256 == fetched_keccak256_without_metadata; + + if !has_metadata || !hashes_without_metadata_match { + tracing::error!( + contract_address = ?address, + identifier = ?identifier, + fetched_keccak256 = ?fetched_keccak256, + fetched_keccak256_without_metadata = ?fetched_keccak256_without_metadata, + info = ?info, + "Bogus verification info fetched for contract", + ); + anyhow::bail!("Internal error: bogus verification info detected"); + } + + // Mark the contract as partial match (regardless of other issues). + info.verification_problems = vec![VerificationProblem::IncorrectMetadata]; + } + + Ok(Some(info)) +} diff --git a/core/node/contract_verification_server/src/cache.rs b/core/node/contract_verification_server/src/cache.rs index c8e367515287..f7ba10c2bf92 100644 --- a/core/node/contract_verification_server/src/cache.rs +++ b/core/node/contract_verification_server/src/cache.rs @@ -5,7 +5,7 @@ use std::{ use tokio::sync::RwLock; use zksync_dal::{Connection, ConnectionPool, Core, CoreDal, DalError}; -use zksync_types::contract_verification_api::CompilerVersions; +use zksync_types::contract_verification::api::CompilerVersions; /// Compiler versions supported by the contract verifier. #[derive(Debug, Clone)] diff --git a/core/node/contract_verification_server/src/tests.rs b/core/node/contract_verification_server/src/tests.rs index 88b14db68733..3eb27056b960 100644 --- a/core/node/contract_verification_server/src/tests.rs +++ b/core/node/contract_verification_server/src/tests.rs @@ -13,7 +13,7 @@ use zksync_dal::{Connection, Core, CoreDal}; use zksync_node_test_utils::create_l2_block; use zksync_types::{ bytecode::{BytecodeHash, BytecodeMarker}, - contract_verification_api::CompilerVersions, + contract_verification::api::CompilerVersions, get_code_key, Address, L2BlockNumber, ProtocolVersion, StorageLog, }; diff --git a/core/node/da_clients/src/avail/client.rs b/core/node/da_clients/src/avail/client.rs index 411a0354d632..d4831ec81ce2 100644 --- a/core/node/da_clients/src/avail/client.rs +++ b/core/node/da_clients/src/avail/client.rs @@ -245,4 +245,27 @@ impl DataAvailabilityClient for AvailClient { fn blob_size_limit(&self) -> Option { Some(RawAvailClient::MAX_BLOB_SIZE) } + + async fn balance(&self) -> Result { + match self.sdk_client.as_ref() { + AvailClientMode::Default(client) => { + let AvailClientConfig::FullClient(default_config) = &self.config.config else { + unreachable!(); // validated in protobuf config + }; + + let ws_client = WsClientBuilder::default() + .build(default_config.api_node_url.clone().as_str()) + .await + .map_err(to_non_retriable_da_error)?; + + Ok(client + .balance(&ws_client) + .await + .map_err(to_non_retriable_da_error)?) + } + AvailClientMode::GasRelay(_) => { + Ok(0) // TODO: implement balance for gas relay (PE-304) + } + } + } } diff --git a/core/node/da_clients/src/avail/sdk.rs b/core/node/da_clients/src/avail/sdk.rs index 8f28e797dc9a..bf6bdcb13ff5 100644 --- a/core/node/da_clients/src/avail/sdk.rs +++ b/core/node/da_clients/src/avail/sdk.rs @@ -3,6 +3,7 @@ use std::{fmt::Debug, sync::Arc, time}; +use anyhow::Context; use backon::{ConstantBuilder, Retryable}; use bytes::Bytes; use jsonrpsee::{ @@ -22,7 +23,6 @@ use crate::utils::to_non_retriable_da_error; const PROTOCOL_VERSION: u8 = 4; -/// An implementation of the `DataAvailabilityClient` trait that interacts with the Avail network. #[derive(Debug, Clone)] pub(crate) struct RawAvailClient { app_id: u32, @@ -344,6 +344,23 @@ impl RawAvailClient { Ok(tx_id) } + + /// Returns the balance of the address controlled by the `keypair` + pub async fn balance(&self, client: &Client) -> anyhow::Result { + let address = to_addr(self.keypair.clone()); + let resp: serde_json::Value = client + .request("state_getStorage", rpc_params![address]) + .await + .context("Error calling state_getStorage RPC")?; + + let balance = resp + .as_str() + .ok_or_else(|| anyhow::anyhow!("Invalid balance"))?; + + balance + .parse() + .context("Unable to parse the account balance") + } } fn blake2(data: Vec) -> [u8; N] { diff --git a/core/node/da_clients/src/celestia/client.rs b/core/node/da_clients/src/celestia/client.rs index df0735d4e1e4..9dc91ed141f5 100644 --- a/core/node/da_clients/src/celestia/client.rs +++ b/core/node/da_clients/src/celestia/client.rs @@ -97,6 +97,13 @@ impl DataAvailabilityClient for CelestiaClient { fn blob_size_limit(&self) -> Option { Some(1973786) // almost 2MB } + + async fn balance(&self) -> Result { + self.client + .balance() + .await + .map_err(to_non_retriable_da_error) + } } impl Debug for CelestiaClient { diff --git a/core/node/da_clients/src/celestia/generated/cosmos.bank.v1beta1.rs b/core/node/da_clients/src/celestia/generated/cosmos.bank.v1beta1.rs new file mode 100644 index 000000000000..3eb8c536c915 --- /dev/null +++ b/core/node/da_clients/src/celestia/generated/cosmos.bank.v1beta1.rs @@ -0,0 +1,1121 @@ +// This file is @generated by prost-build. +/// Params defines the parameters for the bank module. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Params { + #[prost(message, repeated, tag = "1")] + pub send_enabled: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "2")] + pub default_send_enabled: bool, +} +impl ::prost::Name for Params { + const NAME: &'static str = "Params"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.Params".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.Params".into() + } +} +/// SendEnabled maps coin denom to a send_enabled status (whether a denom is +/// sendable). +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SendEnabled { + #[prost(string, tag = "1")] + pub denom: ::prost::alloc::string::String, + #[prost(bool, tag = "2")] + pub enabled: bool, +} +impl ::prost::Name for SendEnabled { + const NAME: &'static str = "SendEnabled"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.SendEnabled".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.SendEnabled".into() + } +} +/// Input models transaction input. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Input { + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "2")] + pub coins: ::prost::alloc::vec::Vec, +} +impl ::prost::Name for Input { + const NAME: &'static str = "Input"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.Input".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.Input".into() + } +} +/// Output models transaction outputs. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Output { + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "2")] + pub coins: ::prost::alloc::vec::Vec, +} +impl ::prost::Name for Output { + const NAME: &'static str = "Output"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.Output".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.Output".into() + } +} +/// Supply represents a struct that passively keeps track of the total supply +/// amounts in the network. +/// This message is deprecated now that supply is indexed by denom. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Supply { + #[prost(message, repeated, tag = "1")] + pub total: ::prost::alloc::vec::Vec, +} +impl ::prost::Name for Supply { + const NAME: &'static str = "Supply"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.Supply".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.Supply".into() + } +} +/// DenomUnit represents a struct that describes a given +/// denomination unit of the basic token. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DenomUnit { + /// denom represents the string name of the given denom unit (e.g uatom). + #[prost(string, tag = "1")] + pub denom: ::prost::alloc::string::String, + /// exponent represents power of 10 exponent that one must + /// raise the base_denom to in order to equal the given DenomUnit's denom + /// 1 denom = 10^exponent base_denom + /// (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with + /// exponent = 6, thus: 1 atom = 10^6 uatom). + #[prost(uint32, tag = "2")] + pub exponent: u32, + /// aliases is a list of string aliases for the given denom + #[prost(string, repeated, tag = "3")] + pub aliases: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +impl ::prost::Name for DenomUnit { + const NAME: &'static str = "DenomUnit"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.DenomUnit".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.DenomUnit".into() + } +} +/// Metadata represents a struct that describes +/// a basic token. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Metadata { + #[prost(string, tag = "1")] + pub description: ::prost::alloc::string::String, + /// denom_units represents the list of DenomUnit's for a given coin + #[prost(message, repeated, tag = "2")] + pub denom_units: ::prost::alloc::vec::Vec, + /// base represents the base denom (should be the DenomUnit with exponent = 0). + #[prost(string, tag = "3")] + pub base: ::prost::alloc::string::String, + /// display indicates the suggested denom that should be + /// displayed in clients. + #[prost(string, tag = "4")] + pub display: ::prost::alloc::string::String, + /// name defines the name of the token (eg: Cosmos Atom) + /// + /// Since: cosmos-sdk 0.43 + #[prost(string, tag = "5")] + pub name: ::prost::alloc::string::String, + /// symbol is the token symbol usually shown on exchanges (eg: ATOM). This can + /// be the same as the display. + /// + /// Since: cosmos-sdk 0.43 + #[prost(string, tag = "6")] + pub symbol: ::prost::alloc::string::String, + /// URI to a document (on or off-chain) that contains additional information. Optional. + /// + /// Since: cosmos-sdk 0.46 + #[prost(string, tag = "7")] + pub uri: ::prost::alloc::string::String, + /// URIHash is a sha256 hash of a document pointed by URI. It's used to verify that + /// the document didn't change. Optional. + /// + /// Since: cosmos-sdk 0.46 + #[prost(string, tag = "8")] + pub uri_hash: ::prost::alloc::string::String, +} +impl ::prost::Name for Metadata { + const NAME: &'static str = "Metadata"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.Metadata".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.Metadata".into() + } +} +/// GenesisState defines the bank module's genesis state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenesisState { + /// params defines all the paramaters of the module. + #[prost(message, optional, tag = "1")] + pub params: ::core::option::Option, + /// balances is an array containing the balances of all the accounts. + #[prost(message, repeated, tag = "2")] + pub balances: ::prost::alloc::vec::Vec, + /// supply represents the total supply. If it is left empty, then supply will be calculated based on the provided + /// balances. Otherwise, it will be used to validate that the sum of the balances equals this amount. + #[prost(message, repeated, tag = "3")] + pub supply: ::prost::alloc::vec::Vec, + /// denom_metadata defines the metadata of the differents coins. + #[prost(message, repeated, tag = "4")] + pub denom_metadata: ::prost::alloc::vec::Vec, +} +impl ::prost::Name for GenesisState { + const NAME: &'static str = "GenesisState"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.GenesisState".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.GenesisState".into() + } +} +/// Balance defines an account address and balance pair used in the bank module's +/// genesis state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Balance { + /// address is the address of the balance holder. + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + /// coins defines the different coins this balance holds. + #[prost(message, repeated, tag = "2")] + pub coins: ::prost::alloc::vec::Vec, +} +impl ::prost::Name for Balance { + const NAME: &'static str = "Balance"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.Balance".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.Balance".into() + } +} +/// QueryBalanceRequest is the request type for the Query/Balance RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryBalanceRequest { + /// address is the address to query balances for. + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + /// denom is the coin denom to query balances for. + #[prost(string, tag = "2")] + pub denom: ::prost::alloc::string::String, +} +impl ::prost::Name for QueryBalanceRequest { + const NAME: &'static str = "QueryBalanceRequest"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryBalanceRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryBalanceRequest".into() + } +} +/// QueryBalanceResponse is the response type for the Query/Balance RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryBalanceResponse { + /// balance is the balance of the coin. + #[prost(message, optional, tag = "1")] + pub balance: ::core::option::Option, +} +impl ::prost::Name for QueryBalanceResponse { + const NAME: &'static str = "QueryBalanceResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryBalanceResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryBalanceResponse".into() + } +} +/// QueryBalanceRequest is the request type for the Query/AllBalances RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryAllBalancesRequest { + /// address is the address to query balances for. + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + /// pagination defines an optional pagination for the request. + #[prost(message, optional, tag = "2")] + pub pagination: ::core::option::Option< + super::super::base::query::PageRequest, + >, +} +impl ::prost::Name for QueryAllBalancesRequest { + const NAME: &'static str = "QueryAllBalancesRequest"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryAllBalancesRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryAllBalancesRequest".into() + } +} +/// QueryAllBalancesResponse is the response type for the Query/AllBalances RPC +/// method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryAllBalancesResponse { + /// balances is the balances of all the coins. + #[prost(message, repeated, tag = "1")] + pub balances: ::prost::alloc::vec::Vec, + /// pagination defines the pagination in the response. + #[prost(message, optional, tag = "2")] + pub pagination: ::core::option::Option< + super::super::base::query::PageResponse, + >, +} +impl ::prost::Name for QueryAllBalancesResponse { + const NAME: &'static str = "QueryAllBalancesResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryAllBalancesResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryAllBalancesResponse".into() + } +} +/// QuerySpendableBalancesRequest defines the gRPC request structure for querying +/// an account's spendable balances. +/// +/// Since: cosmos-sdk 0.46 +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QuerySpendableBalancesRequest { + /// address is the address to query spendable balances for. + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + /// pagination defines an optional pagination for the request. + #[prost(message, optional, tag = "2")] + pub pagination: ::core::option::Option< + super::super::base::query::PageRequest, + >, +} +impl ::prost::Name for QuerySpendableBalancesRequest { + const NAME: &'static str = "QuerySpendableBalancesRequest"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QuerySpendableBalancesRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QuerySpendableBalancesRequest".into() + } +} +/// QuerySpendableBalancesResponse defines the gRPC response structure for querying +/// an account's spendable balances. +/// +/// Since: cosmos-sdk 0.46 +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QuerySpendableBalancesResponse { + /// balances is the spendable balances of all the coins. + #[prost(message, repeated, tag = "1")] + pub balances: ::prost::alloc::vec::Vec, + /// pagination defines the pagination in the response. + #[prost(message, optional, tag = "2")] + pub pagination: ::core::option::Option< + super::super::base::query::PageResponse, + >, +} +impl ::prost::Name for QuerySpendableBalancesResponse { + const NAME: &'static str = "QuerySpendableBalancesResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QuerySpendableBalancesResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QuerySpendableBalancesResponse".into() + } +} +/// QueryTotalSupplyRequest is the request type for the Query/TotalSupply RPC +/// method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryTotalSupplyRequest { + /// pagination defines an optional pagination for the request. + /// + /// Since: cosmos-sdk 0.43 + #[prost(message, optional, tag = "1")] + pub pagination: ::core::option::Option< + super::super::base::query::PageRequest, + >, +} +impl ::prost::Name for QueryTotalSupplyRequest { + const NAME: &'static str = "QueryTotalSupplyRequest"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryTotalSupplyRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryTotalSupplyRequest".into() + } +} +/// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC +/// method +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryTotalSupplyResponse { + /// supply is the supply of the coins + #[prost(message, repeated, tag = "1")] + pub supply: ::prost::alloc::vec::Vec, + /// pagination defines the pagination in the response. + /// + /// Since: cosmos-sdk 0.43 + #[prost(message, optional, tag = "2")] + pub pagination: ::core::option::Option< + super::super::base::query::PageResponse, + >, +} +impl ::prost::Name for QueryTotalSupplyResponse { + const NAME: &'static str = "QueryTotalSupplyResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryTotalSupplyResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryTotalSupplyResponse".into() + } +} +/// QuerySupplyOfRequest is the request type for the Query/SupplyOf RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QuerySupplyOfRequest { + /// denom is the coin denom to query balances for. + #[prost(string, tag = "1")] + pub denom: ::prost::alloc::string::String, +} +impl ::prost::Name for QuerySupplyOfRequest { + const NAME: &'static str = "QuerySupplyOfRequest"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QuerySupplyOfRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QuerySupplyOfRequest".into() + } +} +/// QuerySupplyOfResponse is the response type for the Query/SupplyOf RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QuerySupplyOfResponse { + /// amount is the supply of the coin. + #[prost(message, optional, tag = "1")] + pub amount: ::core::option::Option, +} +impl ::prost::Name for QuerySupplyOfResponse { + const NAME: &'static str = "QuerySupplyOfResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QuerySupplyOfResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QuerySupplyOfResponse".into() + } +} +/// QueryParamsRequest defines the request type for querying x/bank parameters. +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct QueryParamsRequest {} +impl ::prost::Name for QueryParamsRequest { + const NAME: &'static str = "QueryParamsRequest"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryParamsRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryParamsRequest".into() + } +} +/// QueryParamsResponse defines the response type for querying x/bank parameters. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryParamsResponse { + #[prost(message, optional, tag = "1")] + pub params: ::core::option::Option, +} +impl ::prost::Name for QueryParamsResponse { + const NAME: &'static str = "QueryParamsResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryParamsResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryParamsResponse".into() + } +} +/// QueryDenomsMetadataRequest is the request type for the Query/DenomsMetadata RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryDenomsMetadataRequest { + /// pagination defines an optional pagination for the request. + #[prost(message, optional, tag = "1")] + pub pagination: ::core::option::Option< + super::super::base::query::PageRequest, + >, +} +impl ::prost::Name for QueryDenomsMetadataRequest { + const NAME: &'static str = "QueryDenomsMetadataRequest"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryDenomsMetadataRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryDenomsMetadataRequest".into() + } +} +/// QueryDenomsMetadataResponse is the response type for the Query/DenomsMetadata RPC +/// method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryDenomsMetadataResponse { + /// metadata provides the client information for all the registered tokens. + #[prost(message, repeated, tag = "1")] + pub metadatas: ::prost::alloc::vec::Vec, + /// pagination defines the pagination in the response. + #[prost(message, optional, tag = "2")] + pub pagination: ::core::option::Option< + super::super::base::query::PageResponse, + >, +} +impl ::prost::Name for QueryDenomsMetadataResponse { + const NAME: &'static str = "QueryDenomsMetadataResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryDenomsMetadataResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryDenomsMetadataResponse".into() + } +} +/// QueryDenomMetadataRequest is the request type for the Query/DenomMetadata RPC method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryDenomMetadataRequest { + /// denom is the coin denom to query the metadata for. + #[prost(string, tag = "1")] + pub denom: ::prost::alloc::string::String, +} +impl ::prost::Name for QueryDenomMetadataRequest { + const NAME: &'static str = "QueryDenomMetadataRequest"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryDenomMetadataRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryDenomMetadataRequest".into() + } +} +/// QueryDenomMetadataResponse is the response type for the Query/DenomMetadata RPC +/// method. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryDenomMetadataResponse { + /// metadata describes and provides all the client information for the requested token. + #[prost(message, optional, tag = "1")] + pub metadata: ::core::option::Option, +} +impl ::prost::Name for QueryDenomMetadataResponse { + const NAME: &'static str = "QueryDenomMetadataResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryDenomMetadataResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryDenomMetadataResponse".into() + } +} +/// QueryDenomOwnersRequest defines the request type for the DenomOwners RPC query, +/// which queries for a paginated set of all account holders of a particular +/// denomination. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryDenomOwnersRequest { + /// denom defines the coin denomination to query all account holders for. + #[prost(string, tag = "1")] + pub denom: ::prost::alloc::string::String, + /// pagination defines an optional pagination for the request. + #[prost(message, optional, tag = "2")] + pub pagination: ::core::option::Option< + super::super::base::query::PageRequest, + >, +} +impl ::prost::Name for QueryDenomOwnersRequest { + const NAME: &'static str = "QueryDenomOwnersRequest"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryDenomOwnersRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryDenomOwnersRequest".into() + } +} +/// DenomOwner defines structure representing an account that owns or holds a +/// particular denominated token. It contains the account address and account +/// balance of the denominated token. +/// +/// Since: cosmos-sdk 0.46 +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DenomOwner { + /// address defines the address that owns a particular denomination. + #[prost(string, tag = "1")] + pub address: ::prost::alloc::string::String, + /// balance is the balance of the denominated coin for an account. + #[prost(message, optional, tag = "2")] + pub balance: ::core::option::Option, +} +impl ::prost::Name for DenomOwner { + const NAME: &'static str = "DenomOwner"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.DenomOwner".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.DenomOwner".into() + } +} +/// QueryDenomOwnersResponse defines the RPC response of a DenomOwners RPC query. +/// +/// Since: cosmos-sdk 0.46 +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct QueryDenomOwnersResponse { + #[prost(message, repeated, tag = "1")] + pub denom_owners: ::prost::alloc::vec::Vec, + /// pagination defines the pagination in the response. + #[prost(message, optional, tag = "2")] + pub pagination: ::core::option::Option< + super::super::base::query::PageResponse, + >, +} +impl ::prost::Name for QueryDenomOwnersResponse { + const NAME: &'static str = "QueryDenomOwnersResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.QueryDenomOwnersResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.QueryDenomOwnersResponse".into() + } +} +/// Generated client implementations. +pub mod query_client { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + /// Query defines the gRPC querier service. + #[derive(Debug, Clone)] + pub struct QueryClient { + inner: tonic::client::Grpc, + } + impl QueryClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> QueryClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + std::marker::Send + std::marker::Sync, + { + QueryClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// Balance queries the balance of a single coin for a single account. + pub async fn balance( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Query/Balance", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Query", "Balance")); + self.inner.unary(req, path, codec).await + } + /// AllBalances queries the balance of all coins for a single account. + pub async fn all_balances( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Query/AllBalances", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Query", "AllBalances")); + self.inner.unary(req, path, codec).await + } + /// SpendableBalances queries the spenable balance of all coins for a single + /// account. + /// + /// Since: cosmos-sdk 0.46 + pub async fn spendable_balances( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Query/SpendableBalances", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new("cosmos.bank.v1beta1.Query", "SpendableBalances"), + ); + self.inner.unary(req, path, codec).await + } + /// TotalSupply queries the total supply of all coins. + pub async fn total_supply( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Query/TotalSupply", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Query", "TotalSupply")); + self.inner.unary(req, path, codec).await + } + /// SupplyOf queries the supply of a single coin. + pub async fn supply_of( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Query/SupplyOf", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Query", "SupplyOf")); + self.inner.unary(req, path, codec).await + } + /// Params queries the parameters of x/bank module. + pub async fn params( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Query/Params", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Query", "Params")); + self.inner.unary(req, path, codec).await + } + /// DenomsMetadata queries the client metadata of a given coin denomination. + pub async fn denom_metadata( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Query/DenomMetadata", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Query", "DenomMetadata")); + self.inner.unary(req, path, codec).await + } + /// DenomsMetadata queries the client metadata for all registered coin + /// denominations. + pub async fn denoms_metadata( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Query/DenomsMetadata", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Query", "DenomsMetadata")); + self.inner.unary(req, path, codec).await + } + /// DenomOwners queries for all account addresses that own a particular token + /// denomination. + /// + /// Since: cosmos-sdk 0.46 + pub async fn denom_owners( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Query/DenomOwners", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Query", "DenomOwners")); + self.inner.unary(req, path, codec).await + } + } +} +/// MsgSend represents a message to send coins from one account to another. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MsgSend { + #[prost(string, tag = "1")] + pub from_address: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub to_address: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "3")] + pub amount: ::prost::alloc::vec::Vec, +} +impl ::prost::Name for MsgSend { + const NAME: &'static str = "MsgSend"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.MsgSend".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.MsgSend".into() + } +} +/// MsgSendResponse defines the Msg/Send response type. +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct MsgSendResponse {} +impl ::prost::Name for MsgSendResponse { + const NAME: &'static str = "MsgSendResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.MsgSendResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.MsgSendResponse".into() + } +} +/// MsgMultiSend represents an arbitrary multi-in, multi-out send message. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MsgMultiSend { + #[prost(message, repeated, tag = "1")] + pub inputs: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "2")] + pub outputs: ::prost::alloc::vec::Vec, +} +impl ::prost::Name for MsgMultiSend { + const NAME: &'static str = "MsgMultiSend"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.MsgMultiSend".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.MsgMultiSend".into() + } +} +/// MsgMultiSendResponse defines the Msg/MultiSend response type. +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct MsgMultiSendResponse {} +impl ::prost::Name for MsgMultiSendResponse { + const NAME: &'static str = "MsgMultiSendResponse"; + const PACKAGE: &'static str = "cosmos.bank.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.bank.v1beta1.MsgMultiSendResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.bank.v1beta1.MsgMultiSendResponse".into() + } +} +/// Generated client implementations. +pub mod msg_client { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + /// Msg defines the bank Msg service. + #[derive(Debug, Clone)] + pub struct MsgClient { + inner: tonic::client::Grpc, + } + impl MsgClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> MsgClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + std::marker::Send + std::marker::Sync, + { + MsgClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// Send defines a method for sending coins from one account to another account. + pub async fn send( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Msg/Send", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Msg", "Send")); + self.inner.unary(req, path, codec).await + } + /// MultiSend defines a method for sending coins from some accounts to other accounts. + pub async fn multi_send( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/cosmos.bank.v1beta1.Msg/MultiSend", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("cosmos.bank.v1beta1.Msg", "MultiSend")); + self.inner.unary(req, path, codec).await + } + } +} diff --git a/core/node/da_clients/src/celestia/generated/cosmos.base.query.v1beta1.rs b/core/node/da_clients/src/celestia/generated/cosmos.base.query.v1beta1.rs new file mode 100644 index 000000000000..b236f3026d3f --- /dev/null +++ b/core/node/da_clients/src/celestia/generated/cosmos.base.query.v1beta1.rs @@ -0,0 +1,77 @@ +// This file is @generated by prost-build. +/// PageRequest is to be embedded in gRPC request messages for efficient +/// pagination. Ex: +/// +/// message SomeRequest { +/// Foo some_parameter = 1; +/// PageRequest pagination = 2; +/// } +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PageRequest { + /// key is a value returned in PageResponse.next_key to begin + /// querying the next page most efficiently. Only one of offset or key + /// should be set. + #[prost(bytes = "vec", tag = "1")] + pub key: ::prost::alloc::vec::Vec, + /// offset is a numeric offset that can be used when key is unavailable. + /// It is less efficient than using key. Only one of offset or key should + /// be set. + #[prost(uint64, tag = "2")] + pub offset: u64, + /// limit is the total number of results to be returned in the result page. + /// If left empty it will default to a value to be set by each app. + #[prost(uint64, tag = "3")] + pub limit: u64, + /// count_total is set to true to indicate that the result set should include + /// a count of the total number of items available for pagination in UIs. + /// count_total is only respected when offset is used. It is ignored when key + /// is set. + #[prost(bool, tag = "4")] + pub count_total: bool, + /// reverse is set to true if results are to be returned in the descending order. + /// + /// Since: cosmos-sdk 0.43 + #[prost(bool, tag = "5")] + pub reverse: bool, +} +impl ::prost::Name for PageRequest { + const NAME: &'static str = "PageRequest"; + const PACKAGE: &'static str = "cosmos.base.query.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.base.query.v1beta1.PageRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.base.query.v1beta1.PageRequest".into() + } +} +/// PageResponse is to be embedded in gRPC response messages where the +/// corresponding request message has used PageRequest. +/// +/// message SomeResponse { +/// repeated Bar results = 1; +/// PageResponse page = 2; +/// } +#[derive(::serde::Deserialize, ::serde::Serialize)] +#[serde(default)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PageResponse { + /// next_key is the key to be passed to PageRequest.key to + /// query the next page most efficiently. It will be empty if + /// there are no more results. + #[prost(bytes = "vec", tag = "1")] + pub next_key: ::prost::alloc::vec::Vec, + /// total is total number of results available if PageRequest.count_total + /// was set, its value is undefined otherwise + #[prost(uint64, tag = "2")] + pub total: u64, +} +impl ::prost::Name for PageResponse { + const NAME: &'static str = "PageResponse"; + const PACKAGE: &'static str = "cosmos.base.query.v1beta1"; + fn full_name() -> ::prost::alloc::string::String { + "cosmos.base.query.v1beta1.PageResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/cosmos.base.query.v1beta1.PageResponse".into() + } +} diff --git a/core/node/da_clients/src/celestia/mod.rs b/core/node/da_clients/src/celestia/mod.rs index ce648531f282..1baa52466cf2 100644 --- a/core/node/da_clients/src/celestia/mod.rs +++ b/core/node/da_clients/src/celestia/mod.rs @@ -24,6 +24,16 @@ pub mod cosmos { pub mod v1beta1 { include!("generated/cosmos.base.v1beta1.rs"); } + + pub mod query { + include!("generated/cosmos.base.query.v1beta1.rs"); + } + } + + pub mod bank { + pub mod v1beta1 { + include!("generated/cosmos.bank.v1beta1.rs"); + } } pub mod tx { diff --git a/core/node/da_clients/src/celestia/sdk.rs b/core/node/da_clients/src/celestia/sdk.rs index 5fd9aea79f07..11f10d823f31 100644 --- a/core/node/da_clients/src/celestia/sdk.rs +++ b/core/node/da_clients/src/celestia/sdk.rs @@ -20,6 +20,7 @@ use super::{ query_client::QueryClient as AuthQueryClient, BaseAccount, QueryAccountRequest, QueryParamsRequest as QueryAuthParamsRequest, }, + bank::v1beta1::{query_client::QueryClient as BankQueryClient, QueryAllBalancesRequest}, base::{ node::{ service_client::ServiceClient as MinGasPriceClient, @@ -377,6 +378,37 @@ impl RawCelestiaClient { tracing::debug!(tx_hash = %tx_response.txhash, height, "transaction succeeded"); Ok(Some(height)) } + + pub async fn balance(&self) -> anyhow::Result { + let mut auth_query_client = BankQueryClient::new(self.grpc_channel.clone()); + let resp = auth_query_client + .all_balances(QueryAllBalancesRequest { + address: self.address.clone(), + pagination: None, + }) + .await?; + + let micro_tia_balance = resp + .into_inner() + .balances + .into_iter() + .find(|coin| coin.denom == UNITS_SUFFIX) + .map_or_else( + || { + Err(anyhow::anyhow!( + "no balance found for address: {}", + self.address + )) + }, + |coin| { + coin.amount + .parse::() + .map_err(|e| anyhow::anyhow!("failed to parse balance: {}", e)) + }, + )?; + + Ok(micro_tia_balance) + } } /// Returns a `BlobTx` for the given signed tx and blobs. diff --git a/core/node/da_clients/src/eigen/client.rs b/core/node/da_clients/src/eigen/client.rs index d977620526aa..c7404344e7df 100644 --- a/core/node/da_clients/src/eigen/client.rs +++ b/core/node/da_clients/src/eigen/client.rs @@ -62,4 +62,8 @@ impl DataAvailabilityClient for EigenClient { fn blob_size_limit(&self) -> Option { Some(1920 * 1024) // 2mb - 128kb as a buffer } + + async fn balance(&self) -> Result { + Ok(0) // TODO fetch from API when payments are enabled in Eigen (PE-305) + } } diff --git a/core/node/da_clients/src/no_da.rs b/core/node/da_clients/src/no_da.rs index db0557510ed2..ecfa78ba44de 100644 --- a/core/node/da_clients/src/no_da.rs +++ b/core/node/da_clients/src/no_da.rs @@ -25,4 +25,8 @@ impl DataAvailabilityClient for NoDAClient { fn blob_size_limit(&self) -> Option { None } + + async fn balance(&self) -> Result { + Ok(0) + } } diff --git a/core/node/da_clients/src/object_store.rs b/core/node/da_clients/src/object_store.rs index 55764e8260e0..8c652e1e2341 100644 --- a/core/node/da_clients/src/object_store.rs +++ b/core/node/da_clients/src/object_store.rs @@ -87,6 +87,10 @@ impl DataAvailabilityClient for ObjectStoreDAClient { fn blob_size_limit(&self) -> Option { None } + + async fn balance(&self) -> Result { + Ok(0) + } } /// Used as a wrapper for the pubdata to be stored in the GCS. diff --git a/core/node/da_dispatcher/src/da_dispatcher.rs b/core/node/da_dispatcher/src/da_dispatcher.rs index f59a30b362ee..3bdb5406c92a 100644 --- a/core/node/da_dispatcher/src/da_dispatcher.rs +++ b/core/node/da_dispatcher/src/da_dispatcher.rs @@ -103,7 +103,7 @@ impl DataAvailabilityDispatcher { .await?; drop(conn); - for batch in batches { + for batch in &batches { let dispatch_latency = METRICS.blob_dispatch_latency.start(); let dispatch_response = retry(self.config.max_retries(), batch.l1_batch_number, || { self.client @@ -119,14 +119,14 @@ impl DataAvailabilityDispatcher { })?; let dispatch_latency_duration = dispatch_latency.observe(); - let sent_at = Utc::now().naive_utc(); + let sent_at = Utc::now(); let mut conn = self.pool.connection_tagged("da_dispatcher").await?; conn.data_availability_dal() .insert_l1_batch_da( batch.l1_batch_number, dispatch_response.blob_id.as_str(), - sent_at, + sent_at.naive_utc(), ) .await?; drop(conn); @@ -135,6 +135,12 @@ impl DataAvailabilityDispatcher { .last_dispatched_l1_batch .set(batch.l1_batch_number.0 as usize); METRICS.blob_size.observe(batch.pubdata.len()); + METRICS.sealed_to_dispatched_lag.observe( + sent_at + .signed_duration_since(batch.sealed_at) + .to_std() + .context("sent_at has to be higher than sealed_at")?, + ); tracing::info!( "Dispatched a DA for batch_number: {}, pubdata_size: {}, dispatch_latency: {dispatch_latency_duration:?}", batch.l1_batch_number, @@ -142,6 +148,27 @@ impl DataAvailabilityDispatcher { ); } + // We don't need to report this metric every iteration, only once when the balance is changed + if !batches.is_empty() { + let client_arc = Arc::new(self.client.clone_boxed()); + + tokio::spawn(async move { + let balance = client_arc + .balance() + .await + .with_context(|| "Unable to retrieve DA operator balance"); + + match balance { + Ok(balance) => { + METRICS.operator_balance.set(balance); + } + Err(err) => { + tracing::error!("{err}") + } + } + }); + } + Ok(()) } diff --git a/core/node/da_dispatcher/src/metrics.rs b/core/node/da_dispatcher/src/metrics.rs index 67ac5ed68222..2e167f2083b3 100644 --- a/core/node/da_dispatcher/src/metrics.rs +++ b/core/node/da_dispatcher/src/metrics.rs @@ -4,12 +4,12 @@ use vise::{Buckets, Gauge, Histogram, Metrics, Unit}; /// Buckets for `blob_dispatch_latency` (from 0.1 to 120 seconds). const DISPATCH_LATENCIES: Buckets = - Buckets::values(&[0.1, 0.5, 1.0, 2.0, 5.0, 10.0, 30.0, 60.0, 120.0]); + Buckets::values(&[0.1, 0.5, 1.0, 2.0, 5.0, 10.0, 30.0, 60.0, 120.0, 240.0]); #[derive(Debug, Metrics)] #[metrics(prefix = "server_da_dispatcher")] pub(super) struct DataAvailabilityDispatcherMetrics { - /// Latency of the dispatch of the blob. + /// Latency of the dispatch of the blob. Only the communication with DA layer. #[metrics(buckets = DISPATCH_LATENCIES, unit = Unit::Seconds)] pub blob_dispatch_latency: Histogram, /// The duration between the moment when the blob is dispatched and the moment when it is included. @@ -19,7 +19,6 @@ pub(super) struct DataAvailabilityDispatcherMetrics { /// Buckets are bytes ranging from 1 KB to 16 MB, which has to satisfy all blob size values. #[metrics(buckets = Buckets::exponential(1_024.0..=16.0 * 1_024.0 * 1_024.0, 2.0), unit = Unit::Bytes)] pub blob_size: Histogram, - /// Number of transactions resent by the DA dispatcher. #[metrics(buckets = Buckets::linear(0.0..=10.0, 1.0))] pub dispatch_call_retries: Histogram, @@ -27,6 +26,12 @@ pub(super) struct DataAvailabilityDispatcherMetrics { pub last_dispatched_l1_batch: Gauge, /// Last L1 batch that has its inclusion finalized by DA layer. pub last_included_l1_batch: Gauge, + /// The delay between the moment batch was sealed and the moment it was dispatched. Includes + /// both communication with DA layer and time it spends in the queue on the `da_dispatcher` side. + #[metrics(buckets = DISPATCH_LATENCIES, unit = Unit::Seconds)] + pub sealed_to_dispatched_lag: Histogram, + /// The balance of the operator wallet on DA network. + pub operator_balance: Gauge, } #[vise::register] diff --git a/core/node/eth_sender/src/aggregator.rs b/core/node/eth_sender/src/aggregator.rs index 33b9500b2d18..69e0e45a9b0d 100644 --- a/core/node/eth_sender/src/aggregator.rs +++ b/core/node/eth_sender/src/aggregator.rs @@ -69,8 +69,7 @@ impl OperationSkippingRestrictions { ) -> bool { if let Some(reason) = reason { tracing::info!( - "Skipping sending commit operation of type {} for batches {}-{} \ - since {}", + "Skipping sending operation of type {} for batches {}-{} since {}", agg_op.get_action_type(), agg_op.l1_batch_range().start(), agg_op.l1_batch_range().end(), @@ -95,13 +94,13 @@ impl OperationSkippingRestrictions { fn filter_prove_op(&self, prove_op: Option) -> Option { let op = AggregatedOperation::PublishProofOnchain(prove_op?); - self.check_for_continuation(&op, self.commit_restriction) + self.check_for_continuation(&op, self.prove_restriction) .then_some(op) } fn filter_execute_op(&self, execute_op: Option) -> Option { let op = AggregatedOperation::Execute(execute_op?); - self.check_for_continuation(&op, self.commit_restriction) + self.check_for_continuation(&op, self.execute_restriction) .then_some(op) } } diff --git a/core/node/eth_sender/src/eth_tx_aggregator.rs b/core/node/eth_sender/src/eth_tx_aggregator.rs index 8a829ed00faa..bc9d3266ec78 100644 --- a/core/node/eth_sender/src/eth_tx_aggregator.rs +++ b/core/node/eth_sender/src/eth_tx_aggregator.rs @@ -594,6 +594,7 @@ impl EthTxAggregator { stm_protocol_version_id, stm_validator_timelock_address, ), + chain_protocol_version_id, is_gateway, ) .await?; @@ -642,7 +643,11 @@ impl EthTxAggregator { .await; } - fn encode_aggregated_op(&self, op: &AggregatedOperation) -> TxData { + fn encode_aggregated_op( + &self, + op: &AggregatedOperation, + chain_protocol_version_id: ProtocolVersionId, + ) -> TxData { let mut args = vec![Token::Uint(self.rollup_chain_id.as_u64().into())]; let is_op_pre_gateway = op.protocol_version().is_pre_gateway(); @@ -686,8 +691,9 @@ impl EthTxAggregator { (calldata, None) } AggregatedOperation::Execute(op) => { - args.extend(op.into_tokens()); - let encoding_fn = if is_op_pre_gateway { + args.extend(op.encode_for_eth_tx(chain_protocol_version_id)); + let encoding_fn = if is_op_pre_gateway && chain_protocol_version_id.is_pre_gateway() + { &self.functions.post_shared_bridge_execute } else { &self.functions.post_gateway_execute @@ -743,6 +749,7 @@ impl EthTxAggregator { storage: &mut Connection<'_, Core>, aggregated_op: &AggregatedOperation, timelock_contract_address: Address, + chain_protocol_version_id: ProtocolVersionId, is_gateway: bool, ) -> Result { let mut transaction = storage.start_transaction().await.unwrap(); @@ -755,7 +762,8 @@ impl EthTxAggregator { (_, _) => None, }; let nonce = self.get_next_nonce(&mut transaction, sender_addr).await?; - let encoded_aggregated_op = self.encode_aggregated_op(aggregated_op); + let encoded_aggregated_op = + self.encode_aggregated_op(aggregated_op, chain_protocol_version_id); let l1_batch_number_range = aggregated_op.l1_batch_range(); let eth_tx_predicted_gas = match (op_type, is_gateway, self.aggregator.mode()) { diff --git a/core/node/eth_sender/src/tester.rs b/core/node/eth_sender/src/tester.rs index 943e808cfa6b..022e2bc87222 100644 --- a/core/node/eth_sender/src/tester.rs +++ b/core/node/eth_sender/src/tester.rs @@ -13,7 +13,7 @@ use zksync_object_store::MockObjectStore; use zksync_types::{ aggregated_operations::AggregatedActionType, block::L1BatchHeader, commitment::L1BatchCommitmentMode, eth_sender::EthTx, pubdata_da::PubdataSendingMode, - settlement::SettlementMode, Address, L1BatchNumber, ProtocolVersion, H256, + settlement::SettlementMode, Address, L1BatchNumber, ProtocolVersion, ProtocolVersionId, H256, }; use crate::{ @@ -525,6 +525,7 @@ impl EthSenderTester { &mut self.conn.connection().await.unwrap(), &aggregated_operation, Address::random(), + ProtocolVersionId::latest(), self.is_l2, ) .await diff --git a/core/node/eth_sender/src/tests.rs b/core/node/eth_sender/src/tests.rs index f104d222982a..8841f297cadc 100644 --- a/core/node/eth_sender/src/tests.rs +++ b/core/node/eth_sender/src/tests.rs @@ -236,6 +236,7 @@ async fn resend_each_block(commitment_mode: L1BatchCommitmentMode) -> anyhow::Re &mut tester.conn.connection().await.unwrap(), &get_dummy_operation(0), Address::random(), + ProtocolVersionId::latest(), false, ) .await?; diff --git a/core/node/eth_watch/src/client.rs b/core/node/eth_watch/src/client.rs index 03b22df55995..1a48898c131d 100644 --- a/core/node/eth_watch/src/client.rs +++ b/core/node/eth_watch/src/client.rs @@ -15,7 +15,7 @@ use zksync_types::{ abi::ZkChainSpecificUpgradeData, api::{ChainAggProof, Log}, ethabi::{self, decode, encode, Contract, ParamType}, - web3::{keccak256, BlockId, BlockNumber, CallRequest, Filter, FilterBuilder}, + web3::{keccak256, BlockId, BlockNumber, Filter, FilterBuilder}, Address, L1BatchNumber, L2ChainId, SLChainId, H256, L2_NATIVE_TOKEN_VAULT_ADDRESS, SHARED_BRIDGE_ETHER_TOKEN_ADDRESS, U256, U64, }; @@ -511,28 +511,9 @@ where if base_token_l1_address == SHARED_BRIDGE_ETHER_TOKEN_ADDRESS { (String::from("Ether"), String::from("ETH")) } else { - // TODO(EVM-934): support non-standard tokens. - let selectors: [[u8; 4]; 2] = [ - ethabi::short_signature("name", &[]), - ethabi::short_signature("symbol", &[]), - ]; - let types: [ParamType; 2] = [ParamType::String, ParamType::String]; - - let mut decoded_result = vec![]; - for (selector, param_type) in selectors.into_iter().zip(types.into_iter()) { - let request = CallRequest { - to: Some(base_token_l1_address), - data: Some(selector.into()), - ..Default::default() - }; - let result = self.client.call_contract_function(request, None).await?; - // Base tokens are expected to support erc20 metadata - let mut token = ethabi::decode(&[param_type], &result.0) - .expect("base token does not support erc20 metadata"); - decoded_result.push(token.pop().unwrap()); - } - - (decoded_result[0].to_string(), decoded_result[1].to_string()) + // Due to an issue in the upgrade process, the automatically + // deployed wrapped base tokens will contain generic names + (String::from("Base Token"), String::from("BT")) }; let base_token_asset_id = encode_ntv_asset_id( diff --git a/core/node/eth_watch/src/lib.rs b/core/node/eth_watch/src/lib.rs index f866c8e627c5..d5590159046c 100644 --- a/core/node/eth_watch/src/lib.rs +++ b/core/node/eth_watch/src/lib.rs @@ -150,11 +150,13 @@ impl EthWatch { _ = timer.tick() => { /* continue iterations */ } _ = stop_receiver.changed() => break, } - METRICS.eth_poll.inc(); let mut storage = pool.connection_tagged("eth_watch").await?; match self.loop_iteration(&mut storage).await { - Ok(()) => { /* everything went fine */ } + Ok(()) => { + /* everything went fine */ + METRICS.eth_poll.inc(); + } Err(EventProcessorError::Internal(err)) => { tracing::error!("Internal error processing new blocks: {err:?}"); return Err(err); diff --git a/core/node/fee_model/src/l1_gas_price/main_node_fetcher.rs b/core/node/fee_model/src/l1_gas_price/main_node_fetcher.rs index 259a5e3e3fed..587142ae499b 100644 --- a/core/node/fee_model/src/l1_gas_price/main_node_fetcher.rs +++ b/core/node/fee_model/src/l1_gas_price/main_node_fetcher.rs @@ -3,8 +3,9 @@ use std::{ time::Duration, }; +use async_trait::async_trait; use tokio::sync::watch::Receiver; -use zksync_types::fee_model::FeeParams; +use zksync_types::fee_model::{BatchFeeInput, FeeParams}; use zksync_web3_decl::{ client::{DynClient, L2}, error::ClientRpcContext, @@ -15,8 +16,9 @@ use crate::BatchFeeModelInputProvider; const SLEEP_INTERVAL: Duration = Duration::from_secs(5); -/// This structure maintains the known L1 gas price by periodically querying +/// This structure maintains the known fee params/input by periodically querying /// the main node. +/// /// It is required since the main node doesn't only observe the current L1 gas price, /// but also applies adjustments to it in order to smooth out the spikes. /// The same algorithm cannot be consistently replicated on the external node side, @@ -24,28 +26,40 @@ const SLEEP_INTERVAL: Duration = Duration::from_secs(5); #[derive(Debug)] pub struct MainNodeFeeParamsFetcher { client: Box>, - main_node_fee_params: RwLock, + main_node_fee_state: RwLock<(FeeParams, BatchFeeInput)>, } impl MainNodeFeeParamsFetcher { pub fn new(client: Box>) -> Self { + let fee_params = FeeParams::sensible_v1_default(); + let fee_input = fee_params.scale(1.0, 1.0); Self { client: client.for_component("fee_params_fetcher"), - main_node_fee_params: RwLock::new(FeeParams::sensible_v1_default()), + main_node_fee_state: RwLock::new((fee_params, fee_input)), } } pub async fn run(self: Arc, mut stop_receiver: Receiver) -> anyhow::Result<()> { while !*stop_receiver.borrow_and_update() { - let fetch_result = self - .client - .get_fee_params() - .rpc_context("get_fee_params") - .await; - let main_node_fee_params = match fetch_result { - Ok(price) => price, + // We query fee params and fee input together to minimize the potential for them to be + // out of sync. They can still be fetched out of sync in rare circumstances but nothing + // in the system *directly* relies on `BatchFeeModelInputProvider::get_fee_model_params` + // except for `zks_getFeeParams`. Which is likely fine because EN is essentially + // mimicking how it observed the call to main node. + let (params_result, input_result) = tokio::join!( + self.client.get_fee_params().rpc_context("get_fee_params"), + self.client + .get_batch_fee_input() + .rpc_context("get_batch_fee_input") + ); + let fee_state_result = + params_result.and_then(|params| input_result.map(|input| (params, input))); + let main_node_fee_state = match fee_state_result { + Ok((fee_params, fee_input)) => { + (fee_params, BatchFeeInput::PubdataIndependent(fee_input)) + } Err(err) => { - tracing::warn!("Unable to get the gas price: {}", err); + tracing::warn!("Unable to get main node's fee params/input: {}", err); // A delay to avoid spamming the main node with requests. if tokio::time::timeout(SLEEP_INTERVAL, stop_receiver.changed()) .await @@ -56,7 +70,7 @@ impl MainNodeFeeParamsFetcher { continue; } }; - *self.main_node_fee_params.write().unwrap() = main_node_fee_params; + *self.main_node_fee_state.write().unwrap() = main_node_fee_state; if tokio::time::timeout(SLEEP_INTERVAL, stop_receiver.changed()) .await @@ -71,8 +85,18 @@ impl MainNodeFeeParamsFetcher { } } +#[async_trait] impl BatchFeeModelInputProvider for MainNodeFeeParamsFetcher { + async fn get_batch_fee_input_scaled( + &self, + // EN's scale factors are ignored as we have already fetched scaled fee input from main node + _l1_gas_price_scale_factor: f64, + _l1_pubdata_price_scale_factor: f64, + ) -> anyhow::Result { + Ok(self.main_node_fee_state.read().unwrap().1) + } + fn get_fee_model_params(&self) -> FeeParams { - *self.main_node_fee_params.read().unwrap() + self.main_node_fee_state.read().unwrap().0 } } diff --git a/core/node/node_framework/src/implementations/layers/web3_api/server/bridge_addresses.rs b/core/node/node_framework/src/implementations/layers/web3_api/server/bridge_addresses.rs index a515e4cc1db9..b85d74699857 100644 --- a/core/node/node_framework/src/implementations/layers/web3_api/server/bridge_addresses.rs +++ b/core/node/node_framework/src/implementations/layers/web3_api/server/bridge_addresses.rs @@ -80,7 +80,7 @@ impl L1UpdaterInner { // - To not undo the previous change in case of a network error if info.should_use_l2_asset_router { self.bridge_address_updater - .update_l2_shared_bridge(L2_ASSET_ROUTER_ADDRESS) + .update_l2_bridges(L2_ASSET_ROUTER_ADDRESS) .await; } } diff --git a/core/node/node_storage_init/src/external_node/revert.rs b/core/node/node_storage_init/src/external_node/revert.rs index 86d137c6b660..db06a4492bb7 100644 --- a/core/node/node_storage_init/src/external_node/revert.rs +++ b/core/node/node_storage_init/src/external_node/revert.rs @@ -34,6 +34,12 @@ impl RevertStorage for ExternalNodeReverter { Ok(()) } + async fn is_reorg_needed(&self, stop_receiver: watch::Receiver) -> anyhow::Result { + ReorgDetector::new(self.client.clone(), self.pool.clone()) + .check_reorg_presence(stop_receiver) + .await + } + async fn last_correct_batch_for_reorg( &self, stop_receiver: watch::Receiver, diff --git a/core/node/node_storage_init/src/lib.rs b/core/node/node_storage_init/src/lib.rs index 10b0131908ca..f876fa446c4b 100644 --- a/core/node/node_storage_init/src/lib.rs +++ b/core/node/node_storage_init/src/lib.rs @@ -118,7 +118,11 @@ impl NodeStorageInitializer { recovery.initialize_storage(stop_receiver.clone()).await?; } else { anyhow::bail!( - "Snapshot recovery should be performed, but the strategy is not provided" + "Snapshot recovery should be performed, but the strategy is not provided. \ + In most of the cases this error means that the node was first started \ + with snapshots recovery enabled, but then it was disabled. \ + To get rid of this error and have the node sync from genesis \ + please clear the Node's database" ); } } @@ -182,10 +186,7 @@ impl NodeStorageInitializer { ) -> anyhow::Result { // May be `true` if stop signal is received, but the node will shut down without launching any tasks anyway. let initialized = if let Some(reverter) = &self.strategy.block_reverter { - reverter - .last_correct_batch_for_reorg(stop_receiver) - .await? - .is_none() + !reverter.is_reorg_needed(stop_receiver).await? } else { true }; diff --git a/core/node/node_storage_init/src/traits.rs b/core/node/node_storage_init/src/traits.rs index 3b6467764d97..d28b0226d845 100644 --- a/core/node/node_storage_init/src/traits.rs +++ b/core/node/node_storage_init/src/traits.rs @@ -18,6 +18,9 @@ pub trait InitializeStorage: fmt::Debug + Send + Sync + 'static { /// This trait assumes that for any invalid state there exists a batch number to which the storage can be rolled back. #[async_trait::async_trait] pub trait RevertStorage: fmt::Debug + Send + Sync + 'static { + /// Checks whether a reorg is needed for the storage. + async fn is_reorg_needed(&self, stop_receiver: watch::Receiver) -> anyhow::Result; + /// Checks if the storage is invalid state and has to be rolled back. async fn last_correct_batch_for_reorg( &self, diff --git a/core/node/reorg_detector/src/lib.rs b/core/node/reorg_detector/src/lib.rs index d1954ca4b74b..ec5b505d7803 100644 --- a/core/node/reorg_detector/src/lib.rs +++ b/core/node/reorg_detector/src/lib.rs @@ -266,26 +266,32 @@ impl ReorgDetector { &self.health_check } - async fn check_consistency(&mut self) -> Result<(), Error> { + async fn find_last_diverged_batch(&mut self) -> Result, HashMatchError> { let mut storage = self.pool.connection().await?; - let Some(local_l1_batch) = storage + // Create a readonly transaction to get a consistent view of the storage. + let mut storage_tx = storage + .transaction_builder()? + .set_readonly() + .build() + .await?; + let Some(local_l1_batch) = storage_tx .blocks_dal() .get_last_l1_batch_number_with_tree_data() .await? else { - return Ok(()); + return Ok(None); }; - let Some(local_l2_block) = storage.blocks_dal().get_sealed_l2_block_number().await? else { - return Ok(()); + let Some(local_l2_block) = storage_tx.blocks_dal().get_sealed_l2_block_number().await? + else { + return Ok(None); }; + drop(storage_tx); drop(storage); let remote_l1_batch = self.client.sealed_l1_batch_number().await?; let remote_l2_block = self.client.sealed_l2_block_number().await?; - let checked_l1_batch = local_l1_batch.min(remote_l1_batch); let checked_l2_block = local_l2_block.min(remote_l2_block); - let root_hashes_match = self.root_hashes_match(checked_l1_batch).await?; let l2_block_hashes_match = self.l2_block_hashes_match(checked_l2_block).await?; @@ -295,13 +301,21 @@ impl ReorgDetector { // In other cases either there is only a height mismatch which means that one of // the nodes needs to do catching up; however, it is not certain that there is actually // a re-org taking place. - if root_hashes_match && l2_block_hashes_match { + Ok(if root_hashes_match && l2_block_hashes_match { self.event_handler .update_correct_block(checked_l2_block, checked_l1_batch); + None + } else { + let diverged_l1_batch = checked_l1_batch + (root_hashes_match as u32); + self.event_handler.report_divergence(diverged_l1_batch); + Some(diverged_l1_batch) + }) + } + + async fn check_consistency(&mut self) -> Result<(), Error> { + let Some(diverged_l1_batch) = self.find_last_diverged_batch().await? else { return Ok(()); - } - let diverged_l1_batch = checked_l1_batch + (root_hashes_match as u32); - self.event_handler.report_divergence(diverged_l1_batch); + }; // Check that the first L1 batch matches, to make sure that // we are actually tracking the same chain as the main node. @@ -455,15 +469,7 @@ impl ReorgDetector { ) -> Result<(), Error> { while !*stop_receiver.borrow_and_update() { let sleep_interval = match self.check_consistency().await { - Err(Error::HashMatch(HashMatchError::MissingData(MissingData::RootHash))) => { - tracing::debug!("Last L1 batch on the main node doesn't have a state root hash; waiting until it is computed"); - self.sleep_interval / 10 - } - Err(err) if err.is_retriable() => { - tracing::warn!("Following transient error occurred: {err}"); - tracing::info!("Trying again after a delay"); - self.sleep_interval - } + Err(Error::HashMatch(err)) => self.handle_hash_err(err)?, Err(err) => return Err(err), Ok(()) if stop_after_success => return Ok(()), Ok(()) => self.sleep_interval, @@ -480,6 +486,46 @@ impl ReorgDetector { } Ok(()) } + + /// Returns the sleep interval if the error is transient. + fn handle_hash_err(&self, err: HashMatchError) -> Result { + match err { + HashMatchError::MissingData(MissingData::RootHash) => { + tracing::debug!("Last L1 batch on the main node doesn't have a state root hash; waiting until it is computed"); + Ok(self.sleep_interval / 10) + } + err if err.is_retriable() => { + tracing::warn!("Following transient error occurred: {err}"); + tracing::info!("Trying again after a delay"); + Ok(self.sleep_interval) + } + err => Err(err), + } + } + + /// Checks whether a reorg is present. Unlike [`Self::run_once()`], this method doesn't pinpoint the first diverged L1 batch; + /// it just checks whether diverged batches / blocks exist in general. + /// + /// Internally retries transient errors. Returns `Ok(false)` if a stop signal is received. + pub async fn check_reorg_presence( + &mut self, + mut stop_receiver: watch::Receiver, + ) -> anyhow::Result { + while !*stop_receiver.borrow_and_update() { + let sleep_interval = match self.find_last_diverged_batch().await { + Err(err) => self.handle_hash_err(err)?, + Ok(maybe_diverged_batch) => return Ok(maybe_diverged_batch.is_some()), + }; + + if tokio::time::timeout(sleep_interval, stop_receiver.changed()) + .await + .is_ok() + { + break; + } + } + Ok(false) + } } /// Fallible and async predicate for binary search. diff --git a/core/node/reorg_detector/src/tests.rs b/core/node/reorg_detector/src/tests.rs index 5465cf8662d6..64e9c224d224 100644 --- a/core/node/reorg_detector/src/tests.rs +++ b/core/node/reorg_detector/src/tests.rs @@ -312,12 +312,19 @@ async fn reorg_is_detected_on_batch_hash_mismatch() { store_l2_block(&mut storage, 2, l2_block_hash).await; detector.check_consistency().await.unwrap(); + let (_stop_sender, stop_receiver) = watch::channel(false); + assert!(!detector + .check_reorg_presence(stop_receiver.clone()) + .await + .unwrap()); + seal_l1_batch(&mut storage, 2, H256::repeat_byte(0xff)).await; // ^ Hash of L1 batch #2 differs from that on the main node. assert_matches!( detector.check_consistency().await, Err(Error::ReorgDetected(L1BatchNumber(1))) ); + assert!(detector.check_reorg_presence(stop_receiver).await.unwrap()); } #[tokio::test] @@ -621,6 +628,9 @@ async fn reorg_is_detected_based_on_l2_block_hashes(last_correct_l1_batch: u32) detector.check_consistency().await, Err(Error::ReorgDetected(L1BatchNumber(num))) if num == last_correct_l1_batch ); + + let (_stop_sender, stop_receiver) = watch::channel(false); + assert!(detector.check_reorg_presence(stop_receiver).await.unwrap()); } #[derive(Debug)] diff --git a/core/node/state_keeper/src/executor/tests/mod.rs b/core/node/state_keeper/src/executor/tests/mod.rs index 219cacc60c85..8d735e9ed920 100644 --- a/core/node/state_keeper/src/executor/tests/mod.rs +++ b/core/node/state_keeper/src/executor/tests/mod.rs @@ -1,18 +1,20 @@ -// FIXME: move storage-agnostic tests to VM executor crate - use assert_matches::assert_matches; use rand::{thread_rng, Rng}; use test_casing::{test_casing, Product}; use zksync_contracts::l2_message_root; use zksync_dal::{ConnectionPool, Core}; -use zksync_multivm::interface::{BatchTransactionExecutionResult, ExecutionResult, Halt}; +use zksync_multivm::interface::{ + BatchTransactionExecutionResult, Call, CallType, ExecutionResult, Halt, +}; use zksync_test_contracts::{Account, TestContract}; use zksync_types::{ - get_nonce_key, utils::storage_key_for_eth_balance, vm::FastVmMode, web3, Execute, PriorityOpId, - H256, L2_MESSAGE_ROOT_ADDRESS, U256, + get_nonce_key, + utils::{deployed_address_create, storage_key_for_eth_balance}, + vm::FastVmMode, + web3, Execute, PriorityOpId, H256, L2_MESSAGE_ROOT_ADDRESS, U256, }; -use self::tester::{AccountExt, StorageSnapshot, TestConfig, Tester}; +use self::tester::{AccountExt, StorageSnapshot, TestConfig, Tester, TRANSFER_VALUE}; mod read_storage_factory; mod tester; @@ -854,9 +856,9 @@ async fn execute_tx_with_large_packable_bytecode(vm_mode: FastVmMode) { executor.finish_batch().await.unwrap(); } -#[test_casing(2, [FastVmMode::Old, FastVmMode::Shadow])] // new VM doesn't support call tracing yet +#[test_casing(3, FAST_VM_MODES)] #[tokio::test] -async fn execute_tx_with_call_traces(vm_mode: FastVmMode) { +async fn execute_txs_with_call_traces(vm_mode: FastVmMode) { let connection_pool = ConnectionPool::::constrained_test_pool(1).await; let mut alice = Account::random(); let mut tester = Tester::with_config( @@ -876,4 +878,35 @@ async fn execute_tx_with_call_traces(vm_mode: FastVmMode) { assert_matches!(res.tx_result.result, ExecutionResult::Success { .. }); assert!(!res.call_traces.is_empty()); + + find_first_call(&res.call_traces, &|call| { + call.from == alice.address && call.value == TRANSFER_VALUE.into() + }) + .expect("no transfer call"); + + let deploy_tx = alice.deploy_loadnext_tx().tx; + let res = executor.execute_tx(deploy_tx).await.unwrap(); + assert_matches!(res.tx_result.result, ExecutionResult::Success { .. }); + assert!(!res.call_traces.is_empty()); + + let create_call = find_first_call(&res.call_traces, &|call| { + call.from == alice.address && call.r#type == CallType::Create + }) + .expect("no create call"); + + let expected_address = deployed_address_create(alice.address, 0.into()); + assert_eq!(create_call.to, expected_address); + assert!(!create_call.input.is_empty()); +} + +fn find_first_call<'a>(calls: &'a [Call], predicate: &impl Fn(&Call) -> bool) -> Option<&'a Call> { + for call in calls { + if predicate(call) { + return Some(call); + } + if let Some(call) = find_first_call(&call.calls, predicate) { + return Some(call); + } + } + None } diff --git a/core/node/state_keeper/src/executor/tests/tester.rs b/core/node/state_keeper/src/executor/tests/tester.rs index 8b6df7f04840..6c5015fbca46 100644 --- a/core/node/state_keeper/src/executor/tests/tester.rs +++ b/core/node/state_keeper/src/executor/tests/tester.rs @@ -1,7 +1,7 @@ //! Testing harness for the batch executor. //! Contains helper functionality to initialize test context and perform tests without too much boilerplate. -use std::{collections::HashMap, fmt::Debug, str::FromStr, sync::Arc}; +use std::{collections::HashMap, fmt::Debug, sync::Arc}; use assert_matches::assert_matches; use tempfile::TempDir; @@ -42,14 +42,12 @@ use zksync_vm_executor::batch::{MainBatchExecutorFactory, TraceCalls}; use super::{read_storage_factory::RocksdbStorageFactory, StorageType}; use crate::{ - testonly::{self, BASE_SYSTEM_CONTRACTS}, + testonly::{self, apply_genesis_logs, BASE_SYSTEM_CONTRACTS}, tests::{default_l1_batch_env, default_system_env}, AsyncRocksdbCache, }; -fn get_da_contract_address() -> Address { - Address::from_str("7726827caac94a7f9e1b160f7ea819f172f7b6f9").unwrap() -} +pub(super) const TRANSFER_VALUE: u64 = 123_456_789; /// Representation of configuration parameters used by the state keeper. /// Has sensible defaults for most tests, each of which can be overridden. @@ -294,7 +292,7 @@ impl Tester { .await .unwrap(); - // Also setting up the da for tests + // Also setting up the DA for tests Self::setup_da(&mut storage).await; } } @@ -334,37 +332,28 @@ impl Tester { } } - pub async fn setup_contract<'a>( - con: &mut Connection<'a, Core>, - address: Address, - code: Vec, - ) { + async fn setup_contract(conn: &mut Connection<'_, Core>, address: Address, code: Vec) { let hash: H256 = BytecodeHash::for_bytecode(&code).value(); let known_code_key = get_known_code_key(&hash); let code_key = get_code_key(&address); - let logs = vec![ - StorageLog::new_write_log(known_code_key, H256::from_low_u64_be(1u64)), + let logs = [ + StorageLog::new_write_log(known_code_key, H256::from_low_u64_be(1)), StorageLog::new_write_log(code_key, hash), ]; + apply_genesis_logs(conn, &logs).await; - for log in logs { - apply_genesis_log(con, log).await; - } - - let mut factory_deps = HashMap::new(); - factory_deps.insert(hash, code); - - con.factory_deps_dal() + let factory_deps = HashMap::from([(hash, code)]); + conn.factory_deps_dal() .insert_factory_deps(L2BlockNumber(0), &factory_deps) .await .unwrap(); } - async fn setup_da<'a>(con: &mut Connection<'a, Core>) { + async fn setup_da(conn: &mut Connection<'_, Core>) { Self::setup_contract( - con, - get_da_contract_address(), + conn, + Address::repeat_byte(0x23), l2_rollup_da_validator_bytecode(), ) .await; @@ -442,6 +431,7 @@ impl AccountExt for Account { TxType::L2, ) } + fn l1_execute(&mut self, serial_id: PriorityOpId) -> Transaction { self.get_l1_tx(Execute::transfer(Address::random(), 0.into()), serial_id.0) } @@ -505,7 +495,7 @@ impl AccountExt for Account { /// Automatically increments nonce of the account. fn execute_with_gas_limit(&mut self, gas_limit: u32) -> Transaction { self.get_l2_tx_for_execute( - Execute::transfer(Address::random(), 0.into()), + Execute::transfer(Address::random(), TRANSFER_VALUE.into()), Some(testonly::fee(gas_limit)), ) } @@ -766,25 +756,3 @@ impl StorageSnapshot { snapshot } } - -async fn apply_genesis_log<'a>(storage: &mut Connection<'a, Core>, log: StorageLog) { - storage - .storage_logs_dal() - .append_storage_logs(L2BlockNumber(0), &[log]) - .await - .unwrap(); - - if storage - .storage_logs_dedup_dal() - .filter_written_slots(&[log.key.hashed_key()]) - .await - .unwrap() - .is_empty() - { - storage - .storage_logs_dedup_dal() - .insert_initial_writes(L1BatchNumber(0), &[log.key.hashed_key()]) - .await - .unwrap(); - } -} diff --git a/core/node/state_keeper/src/testonly/mod.rs b/core/node/state_keeper/src/testonly/mod.rs index c0f3707f9455..0484fe3198fd 100644 --- a/core/node/state_keeper/src/testonly/mod.rs +++ b/core/node/state_keeper/src/testonly/mod.rs @@ -1,7 +1,7 @@ //! Test utilities that can be used for testing sequencer that may //! be useful outside of this crate. -use std::collections::HashMap; +use std::collections::HashSet; use async_trait::async_trait; use once_cell::sync::Lazy; @@ -15,10 +15,10 @@ use zksync_multivm::interface::{ }; use zksync_state::OwnedStorage; use zksync_types::{ - bytecode::BytecodeHash, commitment::PubdataParams, fee::Fee, get_code_key, get_known_code_key, - u256_to_h256, utils::storage_key_for_standard_token_balance, AccountTreeId, Address, - L1BatchNumber, L2BlockNumber, StorageLog, Transaction, H256, L2_BASE_TOKEN_ADDRESS, - SYSTEM_CONTEXT_MINIMAL_BASE_FEE, U256, + commitment::PubdataParams, fee::Fee, u256_to_h256, + utils::storage_key_for_standard_token_balance, AccountTreeId, Address, L1BatchNumber, + L2BlockNumber, StorageLog, Transaction, L2_BASE_TOKEN_ADDRESS, SYSTEM_CONTEXT_MINIMAL_BASE_FEE, + U256, }; pub mod test_batch_executor; @@ -76,25 +76,28 @@ impl BatchExecutor for MockBatchExecutor { } } -async fn apply_genesis_log<'a>(storage: &mut Connection<'a, Core>, log: StorageLog) { +pub(crate) async fn apply_genesis_logs(storage: &mut Connection<'_, Core>, logs: &[StorageLog]) { storage .storage_logs_dal() - .append_storage_logs(L2BlockNumber(0), &[log]) + .append_storage_logs(L2BlockNumber(0), logs) .await .unwrap(); - if storage + + let all_hashed_keys: Vec<_> = logs.iter().map(|log| log.key.hashed_key()).collect(); + let repeated_writes = storage .storage_logs_dedup_dal() - .filter_written_slots(&[log.key.hashed_key()]) + .filter_written_slots(&all_hashed_keys) .await - .unwrap() - .is_empty() - { - storage - .storage_logs_dedup_dal() - .insert_initial_writes(L1BatchNumber(0), &[log.key.hashed_key()]) - .await - .unwrap(); - } + .unwrap(); + let initial_writes: Vec<_> = HashSet::from_iter(all_hashed_keys) + .difference(&repeated_writes) + .copied() + .collect(); + storage + .storage_logs_dedup_dal() + .insert_initial_writes(L1BatchNumber(0), &initial_writes) + .await + .unwrap(); } /// Adds funds for specified account list. @@ -103,43 +106,18 @@ pub async fn fund(pool: &ConnectionPool, addresses: &[Address]) { let mut storage = pool.connection().await.unwrap(); let eth_amount = U256::from(10u32).pow(U256::from(32)); //10^32 wei - - for address in addresses { - let key = storage_key_for_standard_token_balance( - AccountTreeId::new(L2_BASE_TOKEN_ADDRESS), - address, - ); - let value = u256_to_h256(eth_amount); - let storage_log = StorageLog::new_write_log(key, value); - - apply_genesis_log(&mut storage, storage_log).await; - } -} - -pub async fn setup_contract(pool: &ConnectionPool, address: Address, code: Vec) { - let mut storage = pool.connection().await.unwrap(); - - let hash: H256 = BytecodeHash::for_bytecode(&code).value(); - let known_code_key = get_known_code_key(&hash); - let code_key = get_code_key(&address); - - let logs = vec![ - StorageLog::new_write_log(known_code_key, H256::from_low_u64_be(1u64)), - StorageLog::new_write_log(code_key, hash), - ]; - - for log in logs { - apply_genesis_log(&mut storage, log).await; - } - - let mut factory_deps = HashMap::new(); - factory_deps.insert(hash, code); - - storage - .factory_deps_dal() - .insert_factory_deps(L2BlockNumber(0), &factory_deps) - .await - .unwrap(); + let storage_logs: Vec<_> = addresses + .iter() + .map(|address| { + let key = storage_key_for_standard_token_balance( + AccountTreeId::new(L2_BASE_TOKEN_ADDRESS), + address, + ); + StorageLog::new_write_log(key, u256_to_h256(eth_amount)) + }) + .collect(); + + apply_genesis_logs(&mut storage, &storage_logs).await; } pub(crate) const DEFAULT_GAS_PER_PUBDATA: u32 = 10000; diff --git a/core/tests/loadnext/Cargo.toml b/core/tests/loadnext/Cargo.toml index 91f987035acf..32957f0372ac 100644 --- a/core/tests/loadnext/Cargo.toml +++ b/core/tests/loadnext/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "loadnext" -version = "0.1.0" +version.workspace = true edition.workspace = true authors.workspace = true homepage.workspace = true diff --git a/core/tests/loadnext/src/fs_utils.rs b/core/tests/loadnext/src/fs_utils.rs index 0e5107f40861..9f44b1ff4946 100644 --- a/core/tests/loadnext/src/fs_utils.rs +++ b/core/tests/loadnext/src/fs_utils.rs @@ -17,7 +17,7 @@ pub struct Token { } pub fn read_tokens(network: Network) -> anyhow::Result> { - let home = Workspace::locate().core(); + let home = Workspace::locate().root(); let path = home.join(format!("etc/tokens/{network}.json")); let file = File::open(path)?; let reader = BufReader::new(file); diff --git a/core/tests/recovery-test/package.json b/core/tests/recovery-test/package.json index 8b2ea7f054c0..28c469fc725d 100644 --- a/core/tests/recovery-test/package.json +++ b/core/tests/recovery-test/package.json @@ -23,7 +23,7 @@ "@types/node": "^18.19.15", "@types/node-fetch": "^2.5.7", "chai": "^4.3.4", - "ethers": "^6.7.1", + "ethers": "^6.13.5", "mocha": "^9.0.2", "mocha-steps": "^1.3.0", "node-fetch": "^2.6.1", diff --git a/core/tests/revert-test/package.json b/core/tests/revert-test/package.json index c3be63dff631..7dc2566eb0ef 100644 --- a/core/tests/revert-test/package.json +++ b/core/tests/revert-test/package.json @@ -24,7 +24,7 @@ "@types/node-fetch": "^2.5.7", "chai": "^4.3.4", "ethereumjs-abi": "^0.6.8", - "ethers": "^6.7.1", + "ethers": "^6.13.5", "mocha": "^9.0.2", "mocha-steps": "^1.3.0", "node-fetch": "^2.6.1", diff --git a/core/tests/revert-test/tests/revert-and-restart-en.test.ts b/core/tests/revert-test/tests/revert-and-restart-en.test.ts index ca7f1735b356..a27e3836461a 100644 --- a/core/tests/revert-test/tests/revert-and-restart-en.test.ts +++ b/core/tests/revert-test/tests/revert-and-restart-en.test.ts @@ -54,7 +54,18 @@ function compileBinaries() { console.log('compiling binaries'); run( 'cargo', - ['build', '--release', '--bin', 'zksync_external_node', '--bin', 'zksync_server', '--bin', 'block_reverter'], + [ + 'build', + '--manifest-path', + './core/Cargo.toml', + '--release', + '--bin', + 'zksync_external_node', + '--bin', + 'zksync_server', + '--bin', + 'block_reverter' + ], { cwd: process.env.ZKSYNC_HOME } ); } diff --git a/core/tests/revert-test/tests/utils.ts b/core/tests/revert-test/tests/utils.ts index 8290598a1feb..d2cf9df837ad 100644 --- a/core/tests/revert-test/tests/utils.ts +++ b/core/tests/revert-test/tests/utils.ts @@ -148,7 +148,7 @@ async function runBlockReverter( `; } - const cmd = `cd ${pathToHome} && RUST_LOG=off cargo run --bin block_reverter --release -- ${args.join( + const cmd = `cd ${pathToHome} && RUST_LOG=off cargo run --manifest-path ./core/Cargo.toml --bin block_reverter --release -- ${args.join( ' ' )} ${fileConfigFlags}`; diff --git a/core/tests/ts-integration/hardhat.config.ts b/core/tests/ts-integration/hardhat.config.ts index a96a83ca3ee3..20f3ecd4f4f7 100644 --- a/core/tests/ts-integration/hardhat.config.ts +++ b/core/tests/ts-integration/hardhat.config.ts @@ -4,7 +4,7 @@ import '@matterlabs/hardhat-zksync-vyper'; export default { zksolc: { - version: '1.5.3', + version: '1.5.10', compilerSource: 'binary', settings: { enableEraVMExtensions: true diff --git a/core/tests/ts-integration/package.json b/core/tests/ts-integration/package.json index 3362b9d6a89e..11d9c2d2e4ed 100644 --- a/core/tests/ts-integration/package.json +++ b/core/tests/ts-integration/package.json @@ -24,7 +24,7 @@ "chalk": "^4.0.0", "elliptic": "^6.5.5", "ethereumjs-abi": "^0.6.8", - "ethers": "^6.7.1", + "ethers": "^6.13.5", "hardhat": "=2.22.2", "jest": "^29.0.3", "jest-environment-node": "^29.0.3", diff --git a/core/tests/ts-integration/scripts/compile-yul.ts b/core/tests/ts-integration/scripts/compile-yul.ts index 876caacdfab3..868f7d10ae6f 100644 --- a/core/tests/ts-integration/scripts/compile-yul.ts +++ b/core/tests/ts-integration/scripts/compile-yul.ts @@ -7,7 +7,7 @@ import { getZksolcUrl, saltFromUrl } from '@matterlabs/hardhat-zksync-solc'; import { getCompilersDir } from 'hardhat/internal/util/global-dir'; import path from 'path'; -const COMPILER_VERSION = '1.5.3'; +const COMPILER_VERSION = '1.5.10'; const IS_COMPILER_PRE_RELEASE = false; async function compilerLocation(): Promise { diff --git a/core/tests/ts-integration/src/context-owner.ts b/core/tests/ts-integration/src/context-owner.ts index 57ca54da7b27..72d977cda6db 100644 --- a/core/tests/ts-integration/src/context-owner.ts +++ b/core/tests/ts-integration/src/context-owner.ts @@ -612,9 +612,25 @@ export class TestContextOwner { await this.waitForVmPlayground(); this.reporter.finishAction(); } - this.reporter.startAction(`Tearing down the context`); + this.reporter.startAction(`Collecting funds`); await this.collectFunds(); this.reporter.finishAction(); + this.reporter.startAction(`Destroying providers`); + // Destroy providers so that they drop potentially active connections to the node. Not doing so might cause + // unexpected network errors to propagate during node termination. + try { + this.l1Provider.destroy(); + } catch (err: any) { + // Catch any request cancellation errors that propagate here after destroying L1 provider + console.log(`Caught error while destroying L1 provider: ${err}`); + } + try { + this.l2Provider.destroy(); + } catch (err: any) { + // Catch any request cancellation errors that propagate here after destroying L2 provider + console.log(`Caught error while destroying L2 provider: ${err}`); + } + this.reporter.finishAction(); } catch (error: any) { // Report the issue to the console and mark the last action as failed. this.reporter.error(`An error occurred: ${error.message || error}`); diff --git a/core/tests/ts-integration/src/helpers.ts b/core/tests/ts-integration/src/helpers.ts index 88819c669655..58b698681388 100644 --- a/core/tests/ts-integration/src/helpers.ts +++ b/core/tests/ts-integration/src/helpers.ts @@ -3,7 +3,6 @@ import * as zksync from 'zksync-ethers'; import * as ethers from 'ethers'; import * as hre from 'hardhat'; import { ZkSyncArtifact } from '@matterlabs/hardhat-zksync-solc/dist/src/types'; -import { TransactionReceipt } from 'ethers'; export const SYSTEM_CONTEXT_ADDRESS = '0x000000000000000000000000000000000000800b'; @@ -78,8 +77,8 @@ export async function anyTransaction(wallet: zksync.Wallet): Promise { const MAX_ATTEMPTS = 3; - let txResponse = null; - let txReceipt: TransactionReceipt | null = null; + let txResponse: ethers.TransactionResponse | null = null; + let txReceipt: ethers.TransactionReceipt | null = null; let nonce = Number(await wallet.getNonce()); for (let i = 0; i < MAX_ATTEMPTS; i++) { // Send a dummy transaction and wait for it to execute. We override `maxFeePerGas` as the default ethers behavior @@ -87,11 +86,47 @@ export async function waitForNewL1Batch(wallet: zksync.Wallet): Promise { + // Unlike `waitForTransaction` below, these errors are not wrapped as `EthersError` for some reason + if (e.message.match(/Not enough gas/)) { + console.log( + `Transaction did not have enough gas, likely gas price went up (attempt ${i + 1}/${MAX_ATTEMPTS})` + ); + return null; + } else if (e.message.match(/max fee per gas less than block base fee/)) { + console.log( + `Transaction's max fee per gas was lower than block base fee, likely gas price went up (attempt ${i + 1}/${MAX_ATTEMPTS})` + ); + return null; + } else if (e.message.match(/nonce too low/)) { + if (!txResponse) { + // Our transaction was never accepted to the mempool with this nonce so it must have been used by another transaction. + return wallet.getNonce().then((newNonce) => { + console.log( + `Transaction's nonce is too low, updating from ${nonce} to ${newNonce} (attempt ${i + 1}/${MAX_ATTEMPTS})` + ); + nonce = newNonce; + return null; + }); + } else { + console.log( + `Transaction's nonce is too low, likely previous attempt succeeded, waiting longer (attempt ${i + 1}/${MAX_ATTEMPTS})` + ); + return txResponse; + } + } else { + return Promise.reject(e); + } + }); + if (!txResponse) { + continue; + } } else { console.log('Gas price has not gone up, waiting longer'); } diff --git a/core/tests/ts-integration/src/retry-provider.ts b/core/tests/ts-integration/src/retry-provider.ts index 4c89e0407b9e..9cf63da0638c 100644 --- a/core/tests/ts-integration/src/retry-provider.ts +++ b/core/tests/ts-integration/src/retry-provider.ts @@ -4,6 +4,22 @@ import { Reporter } from './reporter'; import { AugmentedTransactionResponse } from './transaction-response'; import { L1Provider, RetryableL1Wallet } from './l1-provider'; +// Error markers observed on stage so far. +const IGNORED_ERRORS = [ + 'timeout', + 'etimedout', + 'econnrefused', + 'econnreset', + 'bad gateway', + 'service temporarily unavailable', + 'nonetwork' +]; + +function isIgnored(err: any): boolean { + const errString: string = err.toString().toLowerCase(); + return IGNORED_ERRORS.some((sampleErr) => errString.indexOf(sampleErr) !== -1); +} + /** * RetryProvider retries every RPC request if it detects a timeout-related issue on the server side. */ @@ -11,17 +27,39 @@ export class RetryProvider extends zksync.Provider { private readonly reporter: Reporter; private readonly knownTransactionHashes: Set = new Set(); - constructor(_url?: string | { url: string; timeout: number }, network?: ethers.Networkish, reporter?: Reporter) { - let url; + constructor(_url: string | { url: string; timeout: number }, network?: ethers.Networkish, reporter?: Reporter) { + let fetchRequest: ethers.FetchRequest; if (typeof _url === 'object') { - const fetchRequest: ethers.FetchRequest = new ethers.FetchRequest(_url.url); + fetchRequest = new ethers.FetchRequest(_url.url); fetchRequest.timeout = _url.timeout; - url = fetchRequest; } else { - url = _url; + fetchRequest = new ethers.FetchRequest(_url); } + let defaultGetUrlFunc = ethers.FetchRequest.createGetUrlFunc(); + fetchRequest.getUrlFunc = async (req: ethers.FetchRequest, signal?: ethers.FetchCancelSignal) => { + // Retry network requests that failed because of temporary issues (such as timeout, econnreset). + for (let retry = 0; retry < 50; retry++) { + try { + const result = await defaultGetUrlFunc(req, signal); + // If we obtained result not from the first attempt, print a warning. + if (retry != 0) { + this.reporter?.debug(`RPC request ${req} took ${retry} retries to succeed`); + } + return result; + } catch (err: any) { + if (isIgnored(err)) { + // Error is related to timeouts. Sleep a bit and try again. + await zksync.utils.sleep(this.pollingInterval); + continue; + } + // Re-throw any non-timeout-related error. + throw err; + } + } + return Promise.reject(new Error(`Retried too many times, giving up on request=${req}`)); + }; - super(url, network); + super(fetchRequest, network); this.reporter = reporter ?? new Reporter(); } @@ -35,19 +73,7 @@ export class RetryProvider extends zksync.Provider { } return result; } catch (err: any) { - // Error markers observed on stage so far. - const ignoredErrors = [ - 'timeout', - 'etimedout', - 'econnrefused', - 'econnreset', - 'bad gateway', - 'service temporarily unavailable', - 'nonetwork' - ]; - const errString: string = err.toString().toLowerCase(); - const found = ignoredErrors.some((sampleErr) => errString.indexOf(sampleErr) !== -1); - if (found) { + if (isIgnored(err)) { // Error is related to timeouts. Sleep a bit and try again. await zksync.utils.sleep(this.pollingInterval); continue; diff --git a/core/tests/ts-integration/tests/api/contract-verification.test.ts b/core/tests/ts-integration/tests/api/contract-verification.test.ts index 8f8830ce7516..21657bec9950 100644 --- a/core/tests/ts-integration/tests/api/contract-verification.test.ts +++ b/core/tests/ts-integration/tests/api/contract-verification.test.ts @@ -10,7 +10,7 @@ import { NodeMode } from '../../src/types'; // Regular expression to match ISO dates. const DATE_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{6})?/; -const ZKSOLC_VERSION = 'v1.5.3'; +const ZKSOLC_VERSION = 'v1.5.10'; const SOLC_VERSION = '0.8.26'; const ZK_VM_SOLC_VERSION = 'zkVM-0.8.26-1.0.1'; diff --git a/core/tests/ts-integration/tests/api/debug.test.ts b/core/tests/ts-integration/tests/api/debug.test.ts index 2af18c8438b8..8cde65ac2555 100644 --- a/core/tests/ts-integration/tests/api/debug.test.ts +++ b/core/tests/ts-integration/tests/api/debug.test.ts @@ -29,7 +29,7 @@ describe('Debug methods', () => { test('Should not fail for infinity recursion', async () => { const bytecodePath = `${ testMaster.environment().pathToHome - }/core/tests/ts-integration/contracts/zkasm/artifacts/deep_stak.zkasm/zkasm/deep_stak.zkasm.zbin`; + }/core/tests/ts-integration/contracts/zkasm/artifacts/deep_stak.zkasm/deep_stak.zkasm/deep_stak.zkasm.zbin`; const bytecode = fs.readFileSync(bytecodePath, 'utf-8'); const contractFactory = new zksync.ContractFactory([], bytecode, testMaster.mainAccount()); diff --git a/core/tests/ts-integration/tests/fees.test.ts b/core/tests/ts-integration/tests/fees.test.ts index a111f5804852..f598cf49ce02 100644 --- a/core/tests/ts-integration/tests/fees.test.ts +++ b/core/tests/ts-integration/tests/fees.test.ts @@ -410,9 +410,13 @@ testFees('Test fees', function () { }); afterAll(async () => { - await mainNodeSpawner.killAndSpawnMainNode(); // Returning the pubdata price to the default one // Spawning with no options restores defaults. + await mainNodeSpawner.killAndSpawnMainNode(); + + // Wait for current batch to close so gas price returns to normal. + await waitForNewL1Batch(alice); + await testMaster.deinitialize(); __ZKSYNC_TEST_CONTEXT_OWNER__.setL2NodePid(mainNodeSpawner.mainNode!.proc.pid!); }); diff --git a/core/tests/upgrade-test/package.json b/core/tests/upgrade-test/package.json index 5bb23c36d3b8..57aefb7b7caa 100644 --- a/core/tests/upgrade-test/package.json +++ b/core/tests/upgrade-test/package.json @@ -23,7 +23,7 @@ "@types/node-fetch": "^2.5.7", "chai": "^4.3.4", "chai-as-promised": "^7.1.1", - "ethers": "^6.7.1", + "ethers": "^6.13.5", "mocha": "^9.0.2", "mocha-steps": "^1.3.0", "node-fetch": "^2.6.1", diff --git a/core/tests/upgrade-test/tests/upgrade.test.ts b/core/tests/upgrade-test/tests/upgrade.test.ts index 5a1902ec8671..b593e5ad6677 100644 --- a/core/tests/upgrade-test/tests/upgrade.test.ts +++ b/core/tests/upgrade-test/tests/upgrade.test.ts @@ -268,9 +268,10 @@ describe('Upgrade test', function () { bootloaderHash = ethers.hexlify(zksync.utils.hashBytecode(bootloaderCode)); defaultAccountHash = ethers.hexlify(zksync.utils.hashBytecode(defaultAACode)); - await publishBytecode(tester.ethWallet, bytecodeSupplier, bootloaderCode); - await publishBytecode(tester.ethWallet, bytecodeSupplier, defaultAACode); - await publishBytecode(tester.ethWallet, bytecodeSupplier, forceDeployBytecode); + let nonce = await tester.ethWallet.getNonce(); + nonce += await publishBytecode(tester.ethWallet, bytecodeSupplier, bootloaderCode, nonce); + nonce += await publishBytecode(tester.ethWallet, bytecodeSupplier, defaultAACode, nonce); + await publishBytecode(tester.ethWallet, bytecodeSupplier, forceDeployBytecode, nonce); }); step('Schedule governance call', async () => { @@ -523,7 +524,12 @@ function readCode(newPath: string, legacyPath: string): string { } } -async function publishBytecode(wallet: ethers.Wallet, bytecodeSupplierAddr: string, bytecode: string) { +async function publishBytecode( + wallet: ethers.Wallet, + bytecodeSupplierAddr: string, + bytecode: string, + nonce: number +): Promise { const hash = zksync.utils.hashBytecode(bytecode); const abi = [ 'function publishBytecode(bytes calldata _bytecode) public', @@ -533,8 +539,11 @@ async function publishBytecode(wallet: ethers.Wallet, bytecodeSupplierAddr: stri const contract = new ethers.Contract(bytecodeSupplierAddr, abi, wallet); const block = await contract.publishingBlock(hash); if (block == BigInt(0)) { - await (await contract.publishBytecode(bytecode)).wait(); + const tx = await contract.publishBytecode(bytecode, { nonce }); + await tx.wait(); + return 1; } + return 0; } async function checkedRandomTransfer(sender: zksync.Wallet, amount: bigint): Promise { diff --git a/core/tests/vm-benchmark/Cargo.toml b/core/tests/vm-benchmark/Cargo.toml index eb4a5a239252..f7c1bf880bad 100644 --- a/core/tests/vm-benchmark/Cargo.toml +++ b/core/tests/vm-benchmark/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vm-benchmark" -version = "0.1.0" +version.workspace = true edition.workspace = true license.workspace = true publish = false diff --git a/docker/contract-verifier/Dockerfile b/docker/contract-verifier/Dockerfile index d5f3c53db99f..14cae24c0642 100644 --- a/docker/contract-verifier/Dockerfile +++ b/docker/contract-verifier/Dockerfile @@ -17,7 +17,7 @@ ENV RUSTC_WRAPPER=${RUSTC_WRAPPER} WORKDIR /usr/src/zksync COPY . . -RUN cargo build --release --bin zksync_contract_verifier +RUN cargo build --manifest-path ./core/Cargo.toml --release --bin zksync_contract_verifier FROM ghcr.io/matter-labs/zksync-runtime-base:latest @@ -96,7 +96,7 @@ RUN mkdir -p /etc/vyper-bin/0.4.0 \ && mv vyper0.4.0 /etc/vyper-bin/0.4.0/vyper \ && chmod +x /etc/vyper-bin/0.4.0/vyper -COPY --from=builder /usr/src/zksync/target/release/zksync_contract_verifier /usr/bin/ +COPY --from=builder /usr/src/zksync/core/target/release/zksync_contract_verifier /usr/bin/ COPY contracts/system-contracts/zkout/ /contracts/system-contracts/zkout/ # CMD tail -f /dev/null diff --git a/docker/external-node/Dockerfile b/docker/external-node/Dockerfile index 2effe1051b4a..31fab51719a5 100644 --- a/docker/external-node/Dockerfile +++ b/docker/external-node/Dockerfile @@ -15,16 +15,17 @@ ENV RUSTC_WRAPPER=${RUSTC_WRAPPER} WORKDIR /usr/src/zksync COPY . . -RUN cargo build --release --bin zksync_external_node --bin block_reverter +RUN cargo build --manifest-path ./core/Cargo.toml --release --bin zksync_external_node --bin block_reverter FROM ghcr.io/matter-labs/zksync-runtime-base:latest -COPY --from=builder /usr/src/zksync/target/release/zksync_external_node /usr/bin -COPY --from=builder /usr/src/zksync/target/release/block_reverter /usr/bin +COPY --from=builder /usr/src/zksync/core/target/release/zksync_external_node /usr/bin +COPY --from=builder /usr/src/zksync/core/target/release/block_reverter /usr/bin COPY --from=builder /usr/local/cargo/bin/sqlx /usr/bin COPY --from=builder /usr/src/zksync/docker/external-node/entrypoint.sh /usr/bin COPY contracts/system-contracts/zkout/ /contracts/system-contracts/zkout/ COPY contracts/l1-contracts/out/ /contracts/l1-contracts/out/ +COPY contracts/l1-contracts/zkout/ /contracts/l1-contracts/zkout/ COPY contracts/l2-contracts/zkout/ /contracts/l2-contracts/zkout/ COPY etc/tokens/ /etc/tokens/ COPY etc/ERC20/ /etc/ERC20/ diff --git a/docker/proof-fri-gpu-compressor-gar/Dockerfile b/docker/proof-fri-gpu-compressor-gar/Dockerfile index 42127ea6126c..d74440bd009b 100644 --- a/docker/proof-fri-gpu-compressor-gar/Dockerfile +++ b/docker/proof-fri-gpu-compressor-gar/Dockerfile @@ -4,18 +4,15 @@ FROM nvidia/cuda:12.4.0-runtime-ubuntu22.04 as app # HACK copying to root is the only way to make Docker layer caching work for these files for some reason COPY *.bin / -COPY ./setup_fflonk_compact.key /setup_fflonk_compact.key +COPY ./setup_compact.key /setup_compact.key RUN apt-get update && apt-get install -y curl libpq5 ca-certificates && rm -rf /var/lib/apt/lists/* - # copy finalization hints required for assembly generation -COPY --from=proof_fri_gpu /setup_2\^24.key /setup_2\^24.key COPY --from=proof_fri_gpu /prover/data/keys/ /prover/data/keys/ COPY --from=proof_fri_gpu /usr/bin/zksync_proof_fri_compressor /usr/bin/ -ENV CRS_FILE=/setup_2\^24.key -ENV COMPACT_CRS_FILE=/setup_fflonk_compact.key +ENV COMPACT_CRS_FILE=/setup_compact.key ENTRYPOINT ["zksync_proof_fri_compressor"] diff --git a/docker/server-v2/Dockerfile b/docker/server-v2/Dockerfile index 9557156fa7c4..869f6bdb463f 100644 --- a/docker/server-v2/Dockerfile +++ b/docker/server-v2/Dockerfile @@ -17,7 +17,7 @@ WORKDIR /usr/src/zksync COPY . . -RUN cargo build --release --features=rocksdb/io-uring --bin zksync_server --bin block_reverter --bin merkle_tree_consistency_checker +RUN cargo build --manifest-path ./core/Cargo.toml --release --features=rocksdb/io-uring --bin zksync_server --bin block_reverter --bin merkle_tree_consistency_checker FROM ghcr.io/matter-labs/zksync-runtime-base:latest @@ -28,11 +28,12 @@ EXPOSE 3000 EXPOSE 3031 EXPOSE 3030 -COPY --from=builder /usr/src/zksync/target/release/zksync_server /usr/bin -COPY --from=builder /usr/src/zksync/target/release/block_reverter /usr/bin -COPY --from=builder /usr/src/zksync/target/release/merkle_tree_consistency_checker /usr/bin +COPY --from=builder /usr/src/zksync/core/target/release/zksync_server /usr/bin +COPY --from=builder /usr/src/zksync/core/target/release/block_reverter /usr/bin +COPY --from=builder /usr/src/zksync/core/target/release/merkle_tree_consistency_checker /usr/bin COPY contracts/system-contracts/zkout/ /contracts/system-contracts/zkout/ COPY contracts/l1-contracts/out/ /contracts/l1-contracts/out/ +COPY contracts/l1-contracts/zkout/ /contracts/l1-contracts/zkout/ COPY contracts/l2-contracts/zkout/ /contracts/l2-contracts/zkout/ COPY etc/tokens/ /etc/tokens/ COPY etc/ERC20/ /etc/ERC20/ diff --git a/docker/snapshots-creator/Dockerfile b/docker/snapshots-creator/Dockerfile index 2d3c83064981..753020094df7 100644 --- a/docker/snapshots-creator/Dockerfile +++ b/docker/snapshots-creator/Dockerfile @@ -15,13 +15,13 @@ ENV RUSTC_WRAPPER=${RUSTC_WRAPPER} WORKDIR /usr/src/zksync COPY . . -RUN cargo build --release --bin snapshots_creator +RUN cargo build --manifest-path ./core/Cargo.toml --release --bin snapshots_creator FROM ghcr.io/matter-labs/zksync-runtime-base:latest RUN apt-get update && apt-get install -y liburing-dev && \ rm -rf /var/lib/apt/lists/* -COPY --from=builder /usr/src/zksync/target/release/snapshots_creator /usr/bin +COPY --from=builder /usr/src/zksync/core/target/release/snapshots_creator /usr/bin ENTRYPOINT ["snapshots_creator"] diff --git a/docker/verified-sources-fetcher/Dockerfile b/docker/verified-sources-fetcher/Dockerfile index 87475f3187f3..ebc6619582fd 100644 --- a/docker/verified-sources-fetcher/Dockerfile +++ b/docker/verified-sources-fetcher/Dockerfile @@ -16,7 +16,7 @@ ENV RUSTC_WRAPPER=${RUSTC_WRAPPER} WORKDIR /usr/src/zksync COPY . . -RUN cargo build --release --bin verified_sources_fetcher +RUN cargo build --manifest-path ./core/Cargo.toml --release --bin verified_sources_fetcher FROM ghcr.io/matter-labs/zksync-runtime-base:latest @@ -26,6 +26,6 @@ RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor - RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list RUN apt-get update && apt-get install -y google-cloud-cli && rm -rf /var/lib/apt/lists/* -COPY --from=builder /usr/src/zksync/target/release/verified_sources_fetcher /usr/bin/ +COPY --from=builder /usr/src/zksync/core/target/release/verified_sources_fetcher /usr/bin/ ENTRYPOINT ["verified_sources_fetcher"] diff --git a/docs/src/guides/external-node/01_intro.md b/docs/src/guides/external-node/01_intro.md index b5842e160b6c..2218ea3f153b 100644 --- a/docs/src/guides/external-node/01_intro.md +++ b/docs/src/guides/external-node/01_intro.md @@ -129,6 +129,11 @@ calls and transactions. This namespace is disabled by default and can be configured via setting `EN_API_NAMESPACES` as described in the [example config](prepared_configs/mainnet-config.env). +> [!NOTE] +> +> The traces will only start being generated for blocks synced after the debug namespace is enabled, they will not be +> backfilled! The only way to get traces for historical blocks is to fully re-sync the node + Available methods: | Method | Notes | diff --git a/docs/src/guides/external-node/02_configuration.md b/docs/src/guides/external-node/02_configuration.md index 90da7c1eea79..e570b1e9a1a3 100644 --- a/docs/src/guides/external-node/02_configuration.md +++ b/docs/src/guides/external-node/02_configuration.md @@ -52,6 +52,15 @@ There are variables that allow you to fine-tune the limits of the RPC servers, s entries or the limit for the accepted transaction size. Provided files contain sane defaults that are recommended for use, but these can be edited, e.g. to make the Node more/less restrictive. +**Some common api limits config:**\ +`EN_MAX_RESPONSE_BODY_SIZE_MB` (default 10 i.e. 10MB) controls max size of a single response. Hitting the limit will +result in errors similar to:\ +`Response is too big (...)` + +`EN_REQ_ENTITIES_LIMIT` (default 10000) controls max possible limit of entities to be requested at once. Hitting the +limit will result in errors similar to:\ +`Query returned more than 10000 results (...)` + ## JSON-RPC API namespaces There are 7 total supported API namespaces: `eth`, `net`, `web3`, `debug` - standard ones; `zks` - rollup-specific one; diff --git a/docs/src/guides/external-node/docker-compose-examples/mainnet-external-node-docker-compose.yml b/docs/src/guides/external-node/docker-compose-examples/mainnet-external-node-docker-compose.yml index 5ee9de187bf0..30e0ca8b91a5 100644 --- a/docs/src/guides/external-node/docker-compose-examples/mainnet-external-node-docker-compose.yml +++ b/docs/src/guides/external-node/docker-compose-examples/mainnet-external-node-docker-compose.yml @@ -52,7 +52,7 @@ services: # Generation of consensus secrets. # The secrets are generated iff the secrets file doesn't already exist. generate-secrets: - image: "matterlabs/external-node:2.0-v25.1.0" + image: "matterlabs/external-node:2.0-v26.2.1" entrypoint: [ "/configs/generate_secrets.sh", @@ -61,7 +61,7 @@ services: volumes: - ./configs:/configs external-node: - image: "matterlabs/external-node:2.0-v25.1.0" + image: "matterlabs/external-node:2.0-v26.2.1" entrypoint: [ "/usr/bin/entrypoint.sh", diff --git a/docs/src/guides/external-node/docker-compose-examples/testnet-external-node-docker-compose.yml b/docs/src/guides/external-node/docker-compose-examples/testnet-external-node-docker-compose.yml index 42c5861b79d8..aaa185df0984 100644 --- a/docs/src/guides/external-node/docker-compose-examples/testnet-external-node-docker-compose.yml +++ b/docs/src/guides/external-node/docker-compose-examples/testnet-external-node-docker-compose.yml @@ -52,7 +52,7 @@ services: # Generation of consensus secrets. # The secrets are generated iff the secrets file doesn't already exist. generate-secrets: - image: "matterlabs/external-node:2.0-v24.16.0" + image: "matterlabs/external-node:2.0-v26.2.1" entrypoint: [ "/configs/generate_secrets.sh", @@ -61,7 +61,7 @@ services: volumes: - ./configs:/configs external-node: - image: "matterlabs/external-node:2.0-v24.16.0" + image: "matterlabs/external-node:2.0-v26.2.1" entrypoint: [ "/usr/bin/entrypoint.sh", diff --git a/docs/src/guides/external-node/prepared_configs/mainnet-config.env b/docs/src/guides/external-node/prepared_configs/mainnet-config.env index eac24f4ab7ed..536f868fce05 100644 --- a/docs/src/guides/external-node/prepared_configs/mainnet-config.env +++ b/docs/src/guides/external-node/prepared_configs/mainnet-config.env @@ -46,11 +46,11 @@ EN_PUBSUB_POLLING_INTERVAL=200 EN_MAX_NONCE_AHEAD=50 # The multiplier to use when suggesting gas price. Should be higher than one, # otherwise if the L1 prices soar, the suggested gas price won't be sufficient to be included in block. -EN_GAS_PRICE_SCALE_FACTOR=1.2 +EN_GAS_PRICE_SCALE_FACTOR=1.5 # The factor by which to scale the gasLimit -EN_ESTIMATE_GAS_SCALE_FACTOR=1.2 +EN_ESTIMATE_GAS_SCALE_FACTOR=1.3 # The max possible number of gas that `eth_estimateGas` is allowed to overestimate. -EN_ESTIMATE_GAS_ACCEPTABLE_OVERESTIMATION=1000 +EN_ESTIMATE_GAS_ACCEPTABLE_OVERESTIMATION=5000 # Max possible size of an ABI encoded tx (in bytes). # This shouldn't be larger than the value on the main node. EN_MAX_TX_SIZE=1000000 diff --git a/docs/src/guides/external-node/prepared_configs/testnet-goerli-config-deprecated.env b/docs/src/guides/external-node/prepared_configs/testnet-goerli-config-deprecated.env index eb8b6481d75f..995690ef9b10 100644 --- a/docs/src/guides/external-node/prepared_configs/testnet-goerli-config-deprecated.env +++ b/docs/src/guides/external-node/prepared_configs/testnet-goerli-config-deprecated.env @@ -46,11 +46,11 @@ EN_PUBSUB_POLLING_INTERVAL=200 EN_MAX_NONCE_AHEAD=50 # The multiplier to use when suggesting gas price. Should be higher than one, # otherwise if the L1 prices soar, the suggested gas price won't be sufficient to be included in block. -EN_GAS_PRICE_SCALE_FACTOR=1.2 +EN_GAS_PRICE_SCALE_FACTOR=1.5 # The factor by which to scale the gasLimit -EN_ESTIMATE_GAS_SCALE_FACTOR=1.2 +EN_ESTIMATE_GAS_SCALE_FACTOR=1.3 # The max possible number of gas that `eth_estimateGas` is allowed to overestimate. -EN_ESTIMATE_GAS_ACCEPTABLE_OVERESTIMATION=1000 +EN_ESTIMATE_GAS_ACCEPTABLE_OVERESTIMATION=5000 # Max possible size of an ABI encoded tx (in bytes). # This shouldn't be larger than the value on the main node. EN_MAX_TX_SIZE=1000000 diff --git a/docs/src/guides/external-node/prepared_configs/testnet-sepolia-config.env b/docs/src/guides/external-node/prepared_configs/testnet-sepolia-config.env index c8f855b4a4a2..cd7c791898e4 100644 --- a/docs/src/guides/external-node/prepared_configs/testnet-sepolia-config.env +++ b/docs/src/guides/external-node/prepared_configs/testnet-sepolia-config.env @@ -46,11 +46,11 @@ EN_PUBSUB_POLLING_INTERVAL=200 EN_MAX_NONCE_AHEAD=50 # The multiplier to use when suggesting gas price. Should be higher than one, # otherwise if the L1 prices soar, the suggested gas price won't be sufficient to be included in block. -EN_GAS_PRICE_SCALE_FACTOR=1.2 +EN_GAS_PRICE_SCALE_FACTOR=1.5 # The factor by which to scale the gasLimit -EN_ESTIMATE_GAS_SCALE_FACTOR=1.2 +EN_ESTIMATE_GAS_SCALE_FACTOR=1.3 # The max possible number of gas that `eth_estimateGas` is allowed to overestimate. -EN_ESTIMATE_GAS_ACCEPTABLE_OVERESTIMATION=1000 +EN_ESTIMATE_GAS_ACCEPTABLE_OVERESTIMATION=5000 # Max possible size of an ABI encoded tx (in bytes). # This shouldn't be larger than the value on the main node. EN_MAX_TX_SIZE=1000000 diff --git a/etc/env/base/contracts.toml b/etc/env/base/contracts.toml index 1cb22440e33c..d3eaabf92bd8 100644 --- a/etc/env/base/contracts.toml +++ b/etc/env/base/contracts.toml @@ -39,7 +39,7 @@ BLOB_VERSIONED_HASH_RETRIEVER_ADDR = "0x0000000000000000000000000000000000000000 GENESIS_ROOT = "0x09e68951458b18c24ae5f4100160b53c4888c9b3c3c1859cc674bc02236675ad" GENESIS_BATCH_COMMITMENT = "0x7238eab6a0e9f5bb84421feae6b6b9ae80816d490c875d29ff3ded375a3e078f" -GENESIS_ROLLUP_LEAF_INDEX = "64" +GENESIS_ROLLUP_LEAF_INDEX = "64" # Ecosystem-wide params L1_ROLLUP_DA_VALIDATOR = "0x0000000000000000000000000000000000000000" @@ -67,7 +67,7 @@ L1_NATIVE_TOKEN_VAULT_IMPL_ADDR ="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" L1_NATIVE_TOKEN_VAULT_PROXY_ADDR ="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" L2_NATIVE_TOKEN_VAULT_IMPL_ADDR = "0x0000000000000000000000000000000000010004" L2_NATIVE_TOKEN_VAULT_PROXY_ADDR = "0x0000000000000000000000000000000000010004" -L2_SHARED_BRIDGE_IMPL_ADDR = "0x0000000000000000000000000000000000010003" +L2_SHARED_BRIDGE_IMPL_ADDR = "0x0000000000000000000000000000000000010003" L2_SHARED_BRIDGE_ADDR = "0x0000000000000000000000000000000000010003" L2_ERC20_BRIDGE_ADDR = "0x0000000000000000000000000000000000010003" CTM_DEPLOYMENT_TRACKER_IMPL_ADDR ="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" diff --git a/etc/env/base/fri_proof_compressor.toml b/etc/env/base/fri_proof_compressor.toml index a8825ca98613..c8855d6b2a48 100644 --- a/etc/env/base/fri_proof_compressor.toml +++ b/etc/env/base/fri_proof_compressor.toml @@ -5,8 +5,8 @@ prometheus_pushgateway_url = "http://127.0.0.1:9091" prometheus_push_interval_ms = 100 generation_timeout_in_secs = 3600 max_attempts = 5 -universal_setup_path = "../keys/setup/setup_2^24.key" -universal_setup_download_url = "https://storage.googleapis.com/matterlabs-setup-keys-us/setup-keys/setup_2^24.key" +universal_setup_path = "../keys/setup/setup_compact.key" +universal_setup_download_url = "https://storage.googleapis.com/matterlabs-setup-keys-us/setup-keys/setup_compact.key" verify_wrapper_proof = true universal_fflonk_setup_path = "../keys/setup/setup_fflonk_compact.key" universal_fflonk_setup_download_url = "https://storage.googleapis.com/matterlabs-setup-keys-us/setup-keys/setup_fflonk_compact.key" diff --git a/etc/env/file_based/general.yaml b/etc/env/file_based/general.yaml index f15b63a757f7..76d96fd0e8c4 100644 --- a/etc/env/file_based/general.yaml +++ b/etc/env/file_based/general.yaml @@ -182,8 +182,8 @@ proof_compressor: prometheus_push_interval_ms: 100 generation_timeout_in_secs: 3600 max_attempts: 5 - universal_setup_path: keys/setup/setup_2^24.key - universal_setup_download_url: https://storage.googleapis.com/matterlabs-setup-keys-us/setup-keys/setup_2^24.key + universal_setup_path: keys/setup/setup_compact.key + universal_setup_download_url: https://storage.googleapis.com/matterlabs-setup-keys-us/setup-keys/setup_compact.key verify_wrapper_proof: true universal_fflonk_setup_path: keys/setup/setup_fflonk_compact.key universal_fflonk_setup_download_url: https://storage.googleapis.com/matterlabs-setup-keys-us/setup-keys/setup_fflonk_compact.key @@ -359,7 +359,7 @@ pruning: enabled: true chunk_size: 10 removal_delay_sec: 60 - data_retention_sec: 3600 + data_retention_sec: 604800 commitment_generator: max_parallelism: 10 diff --git a/etc/nix/README.md b/etc/nix/README.md index a7cce422e6e6..cd0339c5d224 100644 --- a/etc/nix/README.md +++ b/etc/nix/README.md @@ -1,8 +1,7 @@ # Declarative and Reproducible builds with Nix This directory contains the nix build recipes for various components of this project. Most importantly it is used to -reproducible build `zksync_tee_prover` reproducibly and create a container containing all what is needed to run it on an -SGX machine. +reproducibly build `zksync_tee_prover` and create a container containing all what is needed to run it on an SGX machine. ## Prerequisites @@ -32,34 +31,34 @@ or on nixos in `/etc/nixos/configuration.nix` add the following lines: Build various components of this project with `nix`. -### Build as the CI would +### Build as a CI would ```shell -nix run github:nixos/nixpkgs/nixos-23.11#nixci +nix run github:nixos/nixpkgs/nixos-24.11#nixci -- build -- --no-sandbox ``` ### Build individual parts ```shell -nix build .#zksync +nix build .#tee_prover +nix build .#container-tee-prover-dcap +nix build .#container-tee-prover-azure ``` -or +or `zksync`, which requires an internet connection while building (not reproducible) ```shell -nix build .#zksync.contract_verifier -nix build .#zksync.external_node -nix build .#zksync.server -nix build .#zksync.snapshots_creator -nix build .#zksync.block_reverter +nix build --no-sandbox .#zksync ``` or ```shell -nix build .#tee_prover -nix build .#container-tee-prover-dcap -nix build .#container-tee-prover-azure +nix build --no-sandbox .#zksync.contract_verifier +nix build --no-sandbox .#zksync.external_node +nix build --no-sandbox .#zksync.server +nix build --no-sandbox .#zksync.snapshots_creator +nix build --no-sandbox .#zksync.block_reverter ``` ## Develop @@ -79,6 +78,23 @@ EOF $ direnv allow ``` +### Full development stack + +If you also want `zkstack` and `foundry` you want to use: + +```shell +nix develop --no-sandbox .#devShellAll +``` + +optionally create `.envrc` for `direnv` to automatically load the environment when entering the main directory: + +```shell +$ cat < .envrc +use flake .#devShellAll --no-sandbox +EOF +$ direnv allow +``` + ### Format for commit ```shell diff --git a/etc/nix/container-tee-prover-azure.nix b/etc/nix/container-tee-prover-azure.nix new file mode 100644 index 000000000000..75462dd20de7 --- /dev/null +++ b/etc/nix/container-tee-prover-azure.nix @@ -0,0 +1,64 @@ +{ lib +, pkgs +, teepot +, tee_prover +, container-name ? "zksync-tee-prover-azure" +, isAzure ? true +, tag ? null +, ... +}: +let + name = container-name; + entrypoint = "${teepot.teepot.tee_key_preexec}/bin/tee-key-preexec"; +in +pkgs.lib.tee.sgxGramineContainer + { + inherit name; + inherit tag; + + packages = [ teepot.teepot.tee_key_preexec tee_prover ]; + inherit entrypoint; + inherit isAzure; + + manifest = { + loader = { + argv = [ + entrypoint + "--env-prefix" + "TEE_PROVER_" + "--" + "${tee_prover}/bin/zksync_tee_prover" + ]; + + log_level = "error"; + + env = { + TEE_PROVER_API_URL.passthrough = true; + TEE_PROVER_MAX_RETRIES.passthrough = true; + TEE_PROVER_INITIAL_RETRY_BACKOFF_SEC.passthrough = true; + TEE_PROVER_RETRY_BACKOFF_MULTIPLIER.passthrough = true; + TEE_PROVER_MAX_BACKOFF_SEC.passthrough = true; + API_PROMETHEUS_LISTENER_PORT.passthrough = true; + API_PROMETHEUS_PUSHGATEWAY_URL.passthrough = true; + API_PROMETHEUS_PUSH_INTERVAL_MS.passthrough = true; + + ### DEBUG ### + RUST_BACKTRACE = "1"; + RUST_LOG = "warning,zksync_tee_prover=debug"; + }; + }; + + sgx = { + edmm_enable = false; + enclave_size = "8G"; + max_threads = 128; + }; + }; + } // { + meta = { + description = "SGX on Azure container for the ZKsync TEE prover"; + homepage = "https://github.com/matter-labs/zksync-era/tree/main/core/bin/zksync_tee_prover"; + platforms = [ "x86_64-linux" ]; + license = [ lib.licenses.asl20 lib.licenses.mit ]; + }; +} diff --git a/etc/nix/container-tee-prover-dcap.nix b/etc/nix/container-tee-prover-dcap.nix new file mode 100644 index 000000000000..2da135c8432b --- /dev/null +++ b/etc/nix/container-tee-prover-dcap.nix @@ -0,0 +1,17 @@ +{ lib +, container-tee-prover-azure +, ... +}: container-tee-prover-azure.overrideAttrs + { + isAzure = false; + container-name = "zksync-tee-prover-dcap"; + } + // { + meta = { + description = "SGX DCAP container for the ZKsync TEE prover"; + homepage = "https://github.com/matter-labs/zksync-era/tree/main/core/bin/zksync_tee_prover"; + platforms = [ "x86_64-linux" ]; + license = [ lib.licenses.asl20 lib.licenses.mit ]; + }; +} + diff --git a/etc/nix/container-tee_prover.nix b/etc/nix/container-tee_prover.nix deleted file mode 100644 index cb8ebfb51549..000000000000 --- a/etc/nix/container-tee_prover.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ pkgs -, nixsgxLib -, teepot -, tee_prover -, container-name -, isAzure ? true -, tag ? null -}: -let - name = container-name; - entrypoint = "${teepot.teepot.tee_key_preexec}/bin/tee-key-preexec"; -in -nixsgxLib.mkSGXContainer { - inherit name; - inherit tag; - - packages = [ teepot.teepot.tee_key_preexec tee_prover ]; - inherit entrypoint; - inherit isAzure; - - manifest = { - loader = { - argv = [ - entrypoint - "--env-prefix" - "TEE_PROVER_" - "--" - "${tee_prover}/bin/zksync_tee_prover" - ]; - - log_level = "error"; - - env = { - TEE_PROVER_API_URL.passthrough = true; - TEE_PROVER_MAX_RETRIES.passthrough = true; - TEE_PROVER_INITIAL_RETRY_BACKOFF_SEC.passthrough = true; - TEE_PROVER_RETRY_BACKOFF_MULTIPLIER.passthrough = true; - TEE_PROVER_MAX_BACKOFF_SEC.passthrough = true; - API_PROMETHEUS_LISTENER_PORT.passthrough = true; - API_PROMETHEUS_PUSHGATEWAY_URL.passthrough = true; - API_PROMETHEUS_PUSH_INTERVAL_MS.passthrough = true; - - ### DEBUG ### - RUST_BACKTRACE = "1"; - RUST_LOG = "warning,zksync_tee_prover=debug"; - }; - }; - - sgx = { - edmm_enable = false; - enclave_size = "8G"; - max_threads = 128; - }; - }; -} diff --git a/etc/nix/devshell.nix b/etc/nix/devShell.nix similarity index 54% rename from etc/nix/devshell.nix rename to etc/nix/devShell.nix index 046cd210d162..a63f6c656c2f 100644 --- a/etc/nix/devshell.nix +++ b/etc/nix/devShell.nix @@ -1,22 +1,21 @@ { pkgs -, zksync -, commonArgs +, tee_prover +, coreCommonArgs +, inputs +, ... }: -pkgs.mkShell { - inputsFrom = [ zksync ]; +let + toolchain = pkgs.rust-bin.fromRustupToolchainFile (inputs.src + "/rust-toolchain"); - packages = with pkgs; [ - docker-compose - nodejs - yarn - axel - postgresql - python3 - solc - sqlx-cli - ]; + toolchain_with_src = (toolchain.override { + extensions = [ "rustfmt" "clippy" "rust-src" ]; + }); +in +pkgs.mkShell { + inputsFrom = [ tee_prover ]; + packages = [ ]; - inherit (commonArgs) env hardeningEnable; + inherit (coreCommonArgs) env hardeningEnable; shellHook = '' export ZKSYNC_HOME=$PWD @@ -32,6 +31,7 @@ pkgs.mkShell { fi ''; + RUST_SRC_PATH = "${toolchain_with_src}/lib/rustlib/src/rust/library"; ZK_NIX_LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [ ]; } diff --git a/etc/nix/devShellAll.nix b/etc/nix/devShellAll.nix new file mode 100644 index 000000000000..ed043c30b2eb --- /dev/null +++ b/etc/nix/devShellAll.nix @@ -0,0 +1,28 @@ +{ pkgs +, zksync +, zkstack +, devShell +, foundry-zksync +, ... +}: +let + newshell = (pkgs.mkShell { + inputsFrom = [ zksync zkstack ]; + + packages = with pkgs; [ + docker-compose + nodejs + yarn + axel + postgresql + python3 + solc + sqlx-cli + zkstack + foundry-zksync + nodePackages.prettier + ]; + }); +in +devShell.overrideAttrs + (old: { inherit (newshell) buildInputs nativeBuildInputs; }) diff --git a/etc/nix/foundry-zksync.nix b/etc/nix/foundry-zksync.nix new file mode 100644 index 000000000000..765b019fac3d --- /dev/null +++ b/etc/nix/foundry-zksync.nix @@ -0,0 +1,63 @@ +{ pkgs +, lib +, fetchFromGitHub +, inputs +, ... +}: +let + src = fetchFromGitHub { + owner = "matter-labs"; + repo = "foundry-zksync"; + tag = "0.2.0-zksync.0.0.2"; + hash = "sha256-SEIpt/kQSuYbR0w/DFeXXLMlT7YLP6T7tDDuRioUWlA="; + }; + + toolchain = pkgs.rust-bin.fromRustupToolchainFile "${src}/rust-toolchain"; + + craneLib = (inputs.crane.mkLib pkgs).overrideToolchain toolchain; + + rustPlatform = pkgs.makeRustPlatform { + cargo = toolchain; + rustc = toolchain; + }; +in +craneLib.buildPackage { + # Some crates download stuff from the network while compiling!!!! + # Allows derivation to access network + # + # Users of this package must set options to indicate that the sandbox conditions can be relaxed for this package. + # These are: + # - When used in a flake, set the flake's config with this line: nixConfig.sandbox = false; + # - From the command line with nix , add one of these options: + # - --option sandbox false + # - --no-sandbox + __noChroot = true; + + pname = src.repo; + version = src.tag; + inherit src; + + doCheck = false; + + nativeBuildInputs = with pkgs;[ + pkg-config + rustPlatform.bindgenHook + ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ darwin.DarwinTools ]; + + buildInputs = with pkgs;[ + libusb1.dev + libclang.dev + openssl.dev + lz4.dev + bzip2.dev + rocksdb_8_3 + snappy.dev + ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ darwin.apple_sdk.frameworks.AppKit ]; + + env = { + OPENSSL_NO_VENDOR = "1"; + ROCKSDB_LIB_DIR = "${pkgs.rocksdb_8_3.out}/lib"; + ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb_8_3.out}/include"; + SNAPPY_LIB_DIR = "${pkgs.snappy.out}/lib"; + }; +} diff --git a/etc/nix/tee_prover.nix b/etc/nix/tee_prover.nix index 55545d1bb8e4..315eaf9e169d 100644 --- a/etc/nix/tee_prover.nix +++ b/etc/nix/tee_prover.nix @@ -1,16 +1,17 @@ { craneLib -, commonArgs +, coreCommonArgs +, ... }: let pname = "zksync_tee_prover"; cargoExtraArgs = "--locked -p zksync_tee_prover"; in -craneLib.buildPackage (commonArgs // { +craneLib.buildPackage (coreCommonArgs // { inherit pname; - version = (builtins.fromTOML (builtins.readFile ../../core/bin/zksync_tee_prover/Cargo.toml)).package.version; + version = (builtins.fromTOML (builtins.readFile ../../core/Cargo.toml)).workspace.package.version; inherit cargoExtraArgs; - cargoArtifacts = craneLib.buildDepsOnly (commonArgs // { + cargoArtifacts = craneLib.buildDepsOnly (coreCommonArgs // { inherit pname; inherit cargoExtraArgs; }); @@ -18,4 +19,13 @@ craneLib.buildPackage (commonArgs // { postInstall = '' strip $out/bin/zksync_tee_prover ''; + + # zksync-protobuf has store paths + postPatch = '' + mkdir -p "$TMPDIR/nix-vendor" + cp -Lr "$cargoVendorDir" -T "$TMPDIR/nix-vendor" + sed -i "s|$cargoVendorDir|$TMPDIR/nix-vendor/|g" "$TMPDIR/nix-vendor/config.toml" + chmod -R +w "$TMPDIR/nix-vendor" + cargoVendorDir="$TMPDIR/nix-vendor" + ''; }) diff --git a/etc/nix/zkstack.nix b/etc/nix/zkstack.nix new file mode 100644 index 000000000000..0ec960da3a13 --- /dev/null +++ b/etc/nix/zkstack.nix @@ -0,0 +1,50 @@ +{ craneLib +, zkstackArgs +, ... +}: +craneLib.buildPackage (zkstackArgs // { + # Some crates download stuff from the network while compiling!!!! + # Allows derivation to access the network + # + # Users of this package must set options to indicate that the sandbox conditions can be relaxed for this package. + # These are: + # - In the appropriate nix.conf file (depends on multi vs single user nix installation), add the line: sandbox = relaxed + # - When used in a flake, set the flake's config with this line: nixConfig.sandbox = "relaxed"; + # - Same as above, but disabling the sandbox completely: nixConfig.sandbox = false; + # - From the command line with nix , add one of these options: + # - --option sandbox relaxed + # - --option sandbox false + # - --no-sandbox + # - --relaxed-sandbox + __noChroot = true; + cargoToml = "${zkstackArgs.src}/zkstack_cli/Cargo.toml"; + cargoLock = "${zkstackArgs.src}/zkstack_cli/Cargo.lock"; + + pname = "zkstack"; + + cargoArtifacts = craneLib.buildDepsOnly (zkstackArgs // { + pname = "zkstack-workspace"; + cargoToml = "${zkstackArgs.src}/zkstack_cli/Cargo.toml"; + cargoLock = "${zkstackArgs.src}/zkstack_cli/Cargo.lock"; + postUnpack = '' + cd $sourceRoot/zkstack_cli + sourceRoot="." + ''; + }); + + version = (builtins.fromTOML (builtins.readFile "${zkstackArgs.src}/zkstack_cli/Cargo.toml")).workspace.package.version; + + postUnpack = '' + cd $sourceRoot/zkstack_cli + sourceRoot="." + ''; + + # zksync-protobuf has store paths + postPatch = '' + mkdir -p "$TMPDIR/nix-vendor" + cp -Lr "$cargoVendorDir" -T "$TMPDIR/nix-vendor" + sed -i "s|$cargoVendorDir|$TMPDIR/nix-vendor/|g" "$TMPDIR/nix-vendor/config.toml" + chmod -R +w "$TMPDIR/nix-vendor" + cargoVendorDir="$TMPDIR/nix-vendor" + ''; +}) diff --git a/etc/nix/zksync.nix b/etc/nix/zksync.nix index 1ecac58b5d91..cb002d1b918d 100644 --- a/etc/nix/zksync.nix +++ b/etc/nix/zksync.nix @@ -1,14 +1,32 @@ { craneLib -, commonArgs +, coreCommonArgs +, zkstack +, foundry-zksync +, ... }: -craneLib.buildPackage (commonArgs // { +let + cargoExtraArgs = "--locked --bin zksync_server --bin zksync_contract_verifier --bin zksync_external_node --bin snapshots_creator --bin block_reverter --bin merkle_tree_consistency_checker"; +in +craneLib.buildPackage (coreCommonArgs // { + # Some crates download stuff from the network while compiling!!!! + # Allows derivation to access network + # + # Users of this package must set options to indicate that the sandbox conditions can be relaxed for this package. + # These are: + # - When used in a flake, set the flake's config with this line: nixConfig.sandbox = false; + # - From the command line with nix , add one of these options: + # - --option sandbox false + # - --no-sandbox + __noChroot = true; + pname = "zksync"; - version = (builtins.fromTOML (builtins.readFile ../../core/bin/zksync_tee_prover/Cargo.toml)).package.version; - cargoExtraArgs = "--all"; + version = (builtins.fromTOML (builtins.readFile (coreCommonArgs.src + "/Cargo.toml"))).workspace.package.version; + inherit cargoExtraArgs; - cargoArtifacts = craneLib.buildDepsOnly (commonArgs // { - pname = "zksync-era-workspace"; - }); + buildInputs = coreCommonArgs.buildInputs ++ [ + zkstack + foundry-zksync + ]; outputs = [ "out" @@ -39,4 +57,15 @@ craneLib.buildPackage (commonArgs // { mkdir -p $server/nix-support echo "block_reverter" >> $server/nix-support/propagated-user-env-packages ''; -}) + + # zksync-protobuf has store paths + postPatch = '' + mkdir -p "$TMPDIR/nix-vendor" + cp -Lr "$cargoVendorDir" -T "$TMPDIR/nix-vendor" + sed -i "s|$cargoVendorDir|$TMPDIR/nix-vendor/|g" "$TMPDIR/nix-vendor/config.toml" + chmod -R +w "$TMPDIR/nix-vendor" + cargoVendorDir="$TMPDIR/nix-vendor" + ''; +} +) + diff --git a/flake.lock b/flake.lock index e1905f2a1f65..43bcf9c2b42a 100644 --- a/flake.lock +++ b/flake.lock @@ -1,17 +1,12 @@ { "nodes": { "crane": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, "locked": { - "lastModified": 1722960479, - "narHash": "sha256-NhCkJJQhD5GUib8zN9JrmYGMwt4lCRp6ZVNzIiYCl0Y=", + "lastModified": 1737250794, + "narHash": "sha256-bdIPhvsAKyYQzqAIeay4kOxTHGwLGkhM+IlBIsmMYFI=", "owner": "ipetkov", "repo": "crane", - "rev": "4c6c77920b8d44cd6660c1621dea6b3fc4b4c4f4", + "rev": "c5b7075f4a6d523fe8204618aa9754e56478c0e0", "type": "github" }, "original": { @@ -21,23 +16,17 @@ } }, "crane_2": { - "inputs": { - "nixpkgs": [ - "teepot-flake", - "nixsgx-flake", - "nixpkgs" - ] - }, "locked": { - "lastModified": 1716156051, - "narHash": "sha256-TjUX7WWRcrhuUxDHsR8pDR2N7jitqZehgCVSy3kBeS8=", + "lastModified": 1731974531, + "narHash": "sha256-z7hiGBWsbWwSnu5UMmYyfHEehlSmfB8sCA8iH4nmxm8=", "owner": "ipetkov", "repo": "crane", - "rev": "7443df1c478947bf96a2e699209f53b2db26209d", + "rev": "8ff9c457d60951bdd37a05ae903423de7ff55c6e", "type": "github" }, "original": { "owner": "ipetkov", + "ref": "8ff9c457d60951bdd37a05ae903423de7ff55c6e", "repo": "crane", "type": "github" } @@ -95,11 +84,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -148,7 +137,7 @@ }, "flake-utils-plus_3": { "inputs": { - "flake-utils": "flake-utils_6" + "flake-utils": "flake-utils_5" }, "locked": { "lastModified": 1715533576, @@ -205,24 +194,6 @@ "inputs": { "systems": "systems_4" }, - "locked": { - "lastModified": 1705309234, - "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_5": { - "inputs": { - "systems": "systems_5" - }, "locked": { "lastModified": 1710146030, "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", @@ -237,9 +208,9 @@ "type": "github" } }, - "flake-utils_6": { + "flake-utils_5": { "inputs": { - "systems": "systems_6" + "systems": "systems_5" }, "locked": { "lastModified": 1694529238, @@ -257,43 +228,43 @@ }, "nixpkgs": { "locked": { - "lastModified": 1722869614, - "narHash": "sha256-7ojM1KSk3mzutD7SkrdSflHXEujPvW1u7QuqWoTLXQU=", + "lastModified": 1737404927, + "narHash": "sha256-e1WgPJpIYbOuokjgylcsuoEUCB4Jl2rQXa2LUD6XAG8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "883180e6550c1723395a3a342f830bfc5c371f6b", + "rev": "ae584d90cbd0396a422289ee3efb1f1c9d141dc3", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-24.05", + "ref": "nixos-24.11", "repo": "nixpkgs", "type": "github" } }, "nixpkgs_2": { "locked": { - "lastModified": 1719707984, - "narHash": "sha256-RoxIr/fbndtuKqulGvNCcuzC6KdAib85Q8gXnjzA1dw=", + "lastModified": 1733550349, + "narHash": "sha256-NcGumB4Lr6KSDq+nIqXtNA8QwAQKDSZT7N9OTGWbTrs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "7dca15289a1c2990efbe4680f0923ce14139b042", + "rev": "e2605d0744c2417b09f8bf850dfca42fcf537d34", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-24.05", + "ref": "nixos-24.11", "repo": "nixpkgs", "type": "github" } }, "nixpkgs_3": { "locked": { - "lastModified": 1718428119, - "narHash": "sha256-WdWDpNaq6u1IPtxtYHHWpl5BmabtpmLnMAx0RdJ/vo8=", + "lastModified": 1736320768, + "narHash": "sha256-nIYdTAiKIGnFNugbomgBJR+Xv5F1ZQU+HfaBqJKroC0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e6cea36f83499eb4e9cd184c8a8e823296b50ad5", + "rev": "4bc9c909d9ac828a039f288cf872d16d38185db8", "type": "github" }, "original": { @@ -305,16 +276,16 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1719707984, - "narHash": "sha256-RoxIr/fbndtuKqulGvNCcuzC6KdAib85Q8gXnjzA1dw=", + "lastModified": 1733550349, + "narHash": "sha256-NcGumB4Lr6KSDq+nIqXtNA8QwAQKDSZT7N9OTGWbTrs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "7dca15289a1c2990efbe4680f0923ce14139b042", + "rev": "e2605d0744c2417b09f8bf850dfca42fcf537d34", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-24.05", + "ref": "nixos-24.11", "repo": "nixpkgs", "type": "github" } @@ -341,11 +312,11 @@ "snowfall-lib": "snowfall-lib" }, "locked": { - "lastModified": 1721741092, - "narHash": "sha256-ghFoP5gZpc1i4I4PiVCH00QNZ6s6ipGUcA0P1TsSSC8=", + "lastModified": 1733824290, + "narHash": "sha256-8MKgW3pFW+IxsM/iGfHio91Gym89gh9uNQ3JO4+D8QY=", "owner": "matter-labs", "repo": "nixsgx", - "rev": "be2c19592d0d5601184c52c07ab6d88dec07ffd6", + "rev": "788ff5233053a52421c9f8fa626a936785dda511", "type": "github" }, "original": { @@ -360,11 +331,11 @@ "snowfall-lib": "snowfall-lib_2" }, "locked": { - "lastModified": 1723120465, - "narHash": "sha256-sWu5lKy71hHnSwydhwzG2XgSehjvLfK2iuUtNimvGkg=", + "lastModified": 1733824290, + "narHash": "sha256-8MKgW3pFW+IxsM/iGfHio91Gym89gh9uNQ3JO4+D8QY=", "owner": "matter-labs", "repo": "nixsgx", - "rev": "b080c32f2aa8b3d4b4bc4356a8a513279b6f82ab", + "rev": "788ff5233053a52421c9f8fa626a936785dda511", "type": "github" }, "original": { @@ -379,11 +350,11 @@ "snowfall-lib": "snowfall-lib_3" }, "locked": { - "lastModified": 1717758565, - "narHash": "sha256-yscuZ3ixjwTkqS6ew5cB3Uvy9e807szRlMoPSyQuRJM=", + "lastModified": 1719403531, + "narHash": "sha256-JYqPdAB393YZIndGs5om7EsLUha3fpLckb9RKjKN7Fg=", "owner": "matter-labs", "repo": "nixsgx", - "rev": "49a1ae79d92ccb6ed7cabfe5c5042b1399e3cd3e", + "rev": "3a272950fa21601f31e8ca8b4e4897975069a00a", "type": "github" }, "original": { @@ -407,11 +378,11 @@ "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1722997267, - "narHash": "sha256-8Pncp8IKd0f0N711CRrCGTC4iLfBE+/5kaMqyWxnYic=", + "lastModified": 1737512878, + "narHash": "sha256-dgF6htdmfNnZzVInifks6npnCAyVsIHWSpWNs10RSW0=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "d720bf3cebac38c2426d77ee2e59943012854cb8", + "rev": "06b8ed0eee289fe94c66f1202ced9a6a2c59a14c", "type": "github" }, "original": { @@ -422,7 +393,6 @@ }, "rust-overlay_2": { "inputs": { - "flake-utils": "flake-utils_4", "nixpkgs": [ "teepot-flake", "nixsgx-flake", @@ -430,11 +400,11 @@ ] }, "locked": { - "lastModified": 1717985971, - "narHash": "sha256-24h/qKp0aeI+Ew13WdRF521kY24PYa5HOvw0mlrABjk=", + "lastModified": 1734661750, + "narHash": "sha256-BI58NBdimxu1lnpOrG9XxBz7Cwqy+qIf99zunWofX5w=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "abfe5b3126b1b7e9e4daafc1c6478d17f0b584e7", + "rev": "7d3d910d5fd575e6e8c5600d83d54e5c47273bfe", "type": "github" }, "original": { @@ -462,6 +432,7 @@ }, "original": { "owner": "snowfallorg", + "ref": "c6238c83de101729c5de3a29586ba166a9a65622", "repo": "lib", "type": "github" } @@ -486,6 +457,7 @@ }, "original": { "owner": "snowfallorg", + "ref": "c6238c83de101729c5de3a29586ba166a9a65622", "repo": "lib", "type": "github" } @@ -590,21 +562,6 @@ "type": "github" } }, - "systems_6": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, "teepot-flake": { "inputs": { "crane": "crane_2", @@ -623,11 +580,11 @@ "vault-auth-tee-flake": "vault-auth-tee-flake" }, "locked": { - "lastModified": 1725354393, - "narHash": "sha256-RSiDY3sr0hdlydO3cYtidjVx+OlqIsmcnvsSDSGQPF0=", + "lastModified": 1737116236, + "narHash": "sha256-Bk52s9ENa6zbdaog6YZXMA720K6E+IRDqwYMi5NOWa0=", "owner": "matter-labs", "repo": "teepot", - "rev": "2c21d0161e43dc7a786787c89b84ecd6e8857106", + "rev": "e2c31919c92c5aa803fa3ce75824bea421bb3480", "type": "github" }, "original": { @@ -638,7 +595,7 @@ }, "vault-auth-tee-flake": { "inputs": { - "flake-utils": "flake-utils_5", + "flake-utils": "flake-utils_4", "nixpkgs": [ "teepot-flake", "nixsgx-flake", @@ -647,11 +604,11 @@ "nixsgx-flake": "nixsgx-flake_3" }, "locked": { - "lastModified": 1718012107, - "narHash": "sha256-uKiUBaEOj9f3NCn6oTw5VqoZJxsTXSoAn2IWVB/LSS0=", + "lastModified": 1719832445, + "narHash": "sha256-Dnueq3A1sf8zT+bY6CcuaxPvX4AK7B6Sveqb8YfoY8o=", "owner": "matter-labs", "repo": "vault-auth-tee", - "rev": "b10204436bc2fbad74c5716bd265fad74acc197c", + "rev": "2b53a4387fc8ecfb7826acd93d4895e7e810677d", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 8c08e880910d..2e1e4577ef43 100644 --- a/flake.nix +++ b/flake.nix @@ -12,20 +12,16 @@ }; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; teepot-flake.url = "github:matter-labs/teepot"; nixsgx-flake.url = "github:matter-labs/nixsgx"; flake-utils.url = "github:numtide/flake-utils"; rust-overlay.url = "github:oxalica/rust-overlay"; - crane = { - url = "github:ipetkov/crane?tag=v0.17.3"; - inputs.nixpkgs.follows = "nixpkgs"; - }; + crane.url = "github:ipetkov/crane?tag=v0.20.0"; }; - outputs = { self, nixpkgs, teepot-flake, nixsgx-flake, flake-utils, rust-overlay, crane }: + outputs = { self, nixpkgs, teepot-flake, nixsgx-flake, flake-utils, rust-overlay, crane } @ inputs: let - officialRelease = false; hardeningEnable = [ "fortify3" "pie" "relro" ]; out = system: @@ -46,11 +42,16 @@ packages = { # to ease potential cross-compilation, the overlay is used - inherit (appliedOverlay.zksync-era) zksync tee_prover container-tee-prover-azure container-tee-prover-dcap; + inherit (appliedOverlay.zksync-era) zksync tee_prover zkstack foundry-zksync; default = appliedOverlay.zksync-era.tee_prover; - }; + } // (pkgs.lib.optionalAttrs (pkgs.stdenv.hostPlatform.isx86_64 && pkgs.stdenv.hostPlatform.isLinux) { + inherit (appliedOverlay.zksync-era) container-tee-prover-azure container-tee-prover-dcap; + }); - devShells.default = appliedOverlay.zksync-era.devShell; + devShells = { + inherit (appliedOverlay.zksync-era) devShell devShellAll; + default = appliedOverlay.zksync-era.devShell; + }; }; in flake-utils.lib.eachDefaultSystem out // { @@ -59,16 +60,16 @@ let pkgs = final; - rustVersion = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain; + toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain; rustPlatform = pkgs.makeRustPlatform { - cargo = rustVersion; - rustc = rustVersion; + cargo = toolchain; + rustc = toolchain; }; - craneLib = (crane.mkLib pkgs).overrideToolchain rustVersion; + craneLib = (crane.mkLib pkgs).overrideToolchain toolchain; - commonArgs = { + coreCommonArgs = { nativeBuildInputs = with pkgs;[ pkg-config rustPlatform.bindgenHook @@ -80,25 +81,25 @@ snappy.dev lz4.dev bzip2.dev - rocksdb + rocksdb_8_3 snappy.dev ]; - src = with pkgs.lib.fileset; toSource { - root = ./.; + src = with pkgs.lib.fileset; let root = ./core/.; in toSource { + inherit root; fileset = unions [ - ./Cargo.lock - ./Cargo.toml - ./core - ./prover - ./zkstack_cli - ./.github/release-please/manifest.json + # Default files from crane (Rust and cargo files) + (craneLib.fileset.commonCargoSources root) + # proto files and friends + (fileFilter (file: file.hasExt "proto" || file.hasExt "js" || file.hasExt "ts" || file.hasExt "map" || file.hasExt "json") root) + (maybeMissing ./core/lib/dal/.) ]; }; env = { OPENSSL_NO_VENDOR = "1"; - ROCKSDB_LIB_DIR = "${pkgs.rocksdb.out}/lib"; + ROCKSDB_LIB_DIR = "${pkgs.rocksdb_8_3.out}/lib"; + ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb_8_3.out}/include"; SNAPPY_LIB_DIR = "${pkgs.snappy.out}/lib"; NIX_OUTPATH_USED_AS_RANDOM_SEED = "aaaaaaaaaa"; }; @@ -107,35 +108,32 @@ strictDeps = true; inherit hardeningEnable; }; - in - { - zksync-era = rec { - devShell = pkgs.callPackage ./etc/nix/devshell.nix { - inherit zksync; - inherit commonArgs; - }; - - zksync = pkgs.callPackage ./etc/nix/zksync.nix { - inherit craneLib; - inherit commonArgs; - }; - tee_prover = pkgs.callPackage ./etc/nix/tee_prover.nix { - inherit craneLib; - inherit commonArgs; - }; - - container-tee-prover-azure = pkgs.callPackage ./etc/nix/container-tee_prover.nix { - inherit tee_prover; - isAzure = true; - container-name = "zksync-tee-prover-azure"; - }; - container-tee-prover-dcap = pkgs.callPackage ./etc/nix/container-tee_prover.nix { - inherit tee_prover; - isAzure = false; - container-name = "zksync-tee-prover-dcap"; + zkstackArgs = coreCommonArgs // { + src = with pkgs.lib.fileset; let root = ./.; in toSource { + inherit root; + fileset = unions [ + # Default files from crane (Rust and cargo files) + (craneLib.fileset.commonCargoSources root) + # proto files and friends + (fileFilter (file: file.hasExt "proto" || file.hasExt "js" || file.hasExt "ts" || file.hasExt "map" || file.hasExt "json") ./.) + (maybeMissing ./core/lib/dal/.) + ]; }; }; + in + { + zksync-era = pkgs.lib.makeScope pkgs.newScope ( + self: pkgs.lib.filesystem.packagesFromDirectoryRecursive { + callPackage = package: params: self.callPackage package (params // { + inherit craneLib; + inherit coreCommonArgs; + inherit zkstackArgs; + inputs = inputs // { src = ./.; }; + }); + directory = ./etc/nix; + } + ); }; }; } diff --git a/infrastructure/zk/src/server.ts b/infrastructure/zk/src/server.ts index 8b10559361ae..14a27f6a48be 100644 --- a/infrastructure/zk/src/server.ts +++ b/infrastructure/zk/src/server.ts @@ -17,7 +17,7 @@ export async function server(rebuildTree: boolean, uring: boolean, components?: if (components) { options += ` --components=${components}`; } - await utils.spawn(`cargo run --bin zksync_server --release ${options}`); + await utils.spawn(`cargo run --manifest-path core/Cargo.toml--bin zksync_server --release ${options}`); } export async function externalNode(reinit: boolean = false, args: string[]) { @@ -37,7 +37,9 @@ export async function externalNode(reinit: boolean = false, args: string[]) { clean(path.dirname(process.env.EN_MERKLE_TREE_PATH!)); } - await utils.spawn(`cargo run --release --bin zksync_external_node -- ${args.join(' ')}`); + await utils.spawn( + `cargo run --manifest-path core/Cargo.toml --release --bin zksync_external_node -- ${args.join(' ')}` + ); } async function create_genesis(cmd: string) { @@ -61,7 +63,7 @@ async function create_genesis(cmd: string) { export async function genesisFromSources() { // Note that that all the chains have the same chainId at genesis. It will be changed // via an upgrade transaction during the registration of the chain. - await create_genesis('cargo run --bin zksync_server --release -- --genesis'); + await create_genesis('cargo run --manifest-path core/Cargo.toml --bin zksync_server --release -- --genesis'); } export async function genesisFromBinary() { diff --git a/prover/CHANGELOG.md b/prover/CHANGELOG.md index e99c20193eb5..68a02884328b 100644 --- a/prover/CHANGELOG.md +++ b/prover/CHANGELOG.md @@ -1,5 +1,29 @@ # Changelog +## [18.0.0](https://github.com/matter-labs/zksync-era/compare/prover-v17.1.1...prover-v18.0.0) (2025-01-27) + + +### ⚠ BREAKING CHANGES + +* **contracts:** gateway integration ([#1934](https://github.com/matter-labs/zksync-era/issues/1934)) + +### Features + +* Compressor optimizations ([#3476](https://github.com/matter-labs/zksync-era/issues/3476)) ([3e931be](https://github.com/matter-labs/zksync-era/commit/3e931be6bddaacbd7d029c537db03a3c191fdc21)) +* **consensus:** Added view_timeout to consensus config ([#3383](https://github.com/matter-labs/zksync-era/issues/3383)) ([fc02a8f](https://github.com/matter-labs/zksync-era/commit/fc02a8f1c9f0bffb438fb27769d6dced3ce14cd9)) +* **consensus:** Update consensus dependencies ([#3339](https://github.com/matter-labs/zksync-era/issues/3339)) ([aa9575f](https://github.com/matter-labs/zksync-era/commit/aa9575fccbbc941f416d597256442afa974efd0a)) +* **contracts:** gateway integration ([#1934](https://github.com/matter-labs/zksync-era/issues/1934)) ([f06cb79](https://github.com/matter-labs/zksync-era/commit/f06cb79883bf320f50089099e0abeb95eaace470)) +* **eth-watch:** Change protocol upgrade schema ([#3435](https://github.com/matter-labs/zksync-era/issues/3435)) ([2c778fd](https://github.com/matter-labs/zksync-era/commit/2c778fdd3fcd1e774bcb945f14a640ccf4227a2f)) +* FFLONK support for compressor ([#3359](https://github.com/matter-labs/zksync-era/issues/3359)) ([1a297be](https://github.com/matter-labs/zksync-era/commit/1a297bedd226c56fc2ba02dc54d79129a271a1eb)) +* Support stable compiler for VM (and some other crates) ([#3248](https://github.com/matter-labs/zksync-era/issues/3248)) ([cbee99d](https://github.com/matter-labs/zksync-era/commit/cbee99d8661b38aa6b49784c3934b8070a743fb4)) + + +### Bug Fixes + +* added missing quote in prover query ([#3347](https://github.com/matter-labs/zksync-era/issues/3347)) ([668ca51](https://github.com/matter-labs/zksync-era/commit/668ca51f5d52646e64b19b973acec05daa1c6f09)) +* Compressor setup data ([#3526](https://github.com/matter-labs/zksync-era/issues/3526)) ([62aea8b](https://github.com/matter-labs/zksync-era/commit/62aea8b4dcd986587de2cf17979e1042307d6b3e)) +* **prover:** Create reqwest client only once ([#3324](https://github.com/matter-labs/zksync-era/issues/3324)) ([40f8123](https://github.com/matter-labs/zksync-era/commit/40f8123a67970efbba3519f7954f807958a76cff)) + ## [17.1.1](https://github.com/matter-labs/zksync-era/compare/prover-v17.1.0...prover-v17.1.1) (2024-11-26) diff --git a/prover/Cargo.lock b/prover/Cargo.lock index 761c9e398cb4..bc52f1ab2905 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -625,9 +625,9 @@ dependencies = [ [[package]] name = "boojum" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14bd053feb7173130679a2119e105b5e78af7eb6b0e752de6793e4ee63d8e899" +checksum = "d689807d79092f8f7cfcb72a2313a43da77d56314e41324810566f385875c185" dependencies = [ "arrayvec 0.7.6", "bincode", @@ -657,9 +657,9 @@ dependencies = [ [[package]] name = "boojum-cuda" -version = "0.152.10" +version = "0.152.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd43bc7fc457920cb3b823e4f95ffbbf180b2c48b8d643125cd121325cdd8db" +checksum = "896aeb550e4b92e6c96858c1d0aa8413c00f97fb91f321a2bf3ed912942870f8" dependencies = [ "boojum", "cmake", @@ -803,11 +803,38 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "circuit_definitions" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ebc81d5c2f6ee8de436c242f6466fb315fe25afcbc81aa1c47dfca39a55403" +checksum = "1f04f9c7c6b39255199aaba49802c5f40f95bcff24f5a456446a912d254f4bb1" dependencies = [ "circuit_encodings", "crossbeam", @@ -819,26 +846,26 @@ dependencies = [ [[package]] name = "circuit_encodings" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33375d2448a78c1aed9b8755f7939a6b6f19e2fa80f44f4930a5b4c2bb7cbb44" +checksum = "fc3399f1981164c3c687ea15b1eedd35a16f28069c845a24530de21f996f3fdd" dependencies = [ "derivative", "serde", - "zk_evm 0.150.19", + "zk_evm 0.150.20", "zkevm_circuits", ] [[package]] name = "circuit_sequencer_api" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2fec5c28e5a9f085279e70e13b2eebb63a95ee0bfb99d58095ac01c1c7b256" +checksum = "b5583037ec61607ac481b0c887b7fb4f860e65c92c6f3f7be74f6bab7c40c3ce" dependencies = [ "derivative", "rayon", "serde", - "zk_evm 0.150.19", + "zk_evm 0.150.20", "zksync_bellman", ] @@ -1706,9 +1733,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "era_cudart" -version = "0.152.10" +version = "0.152.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f881cf689ba889bb0fa04c0e71aba701acd7fafd3fa545e3f2782f2a8c0ba0" +checksum = "6ff6fc4fba6bf756cdebd6750161d280af2859d217dad89bfb2823ac760bf0e8" dependencies = [ "bitflags 2.6.0", "era_cudart_sys", @@ -1717,11 +1744,11 @@ dependencies = [ [[package]] name = "era_cudart_sys" -version = "0.152.10" +version = "0.152.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f29cbd9e6d97fc1f05b484f960e921fe69548b4773a361b2e403e4cb9d6d575" +checksum = "7e0daeb39d2111a868a50e0bd7d90fa355f93022038088c0dd865bbdda1113ef" dependencies = [ - "serde_json", + "regex-lite", ] [[package]] @@ -1838,9 +1865,9 @@ dependencies = [ [[package]] name = "fflonk" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63d70f1cbf9e572ccaf22ca1dfce4b93ff48b9a5e8dd70de50d87edb960d173" +checksum = "b36c5fa909ab71b7eb4b8f7fd092f72ed83b93f2615e42f245ca808d8f308917" dependencies = [ "bincode", "byteorder", @@ -1855,9 +1882,9 @@ dependencies = [ [[package]] name = "fflonk-cuda" -version = "0.152.10" +version = "0.152.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b008e6158c95747b3b135adbd7f6d563c406849a10c00abfef109b4d0442a589" +checksum = "890b635123fe176814ddbda1fbe006c55ca02375e5dde83539018f283219a8ba" dependencies = [ "bincode", "byteorder", @@ -1975,9 +2002,9 @@ dependencies = [ [[package]] name = "franklin-crypto" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d7b8e5864df7f3747e5e64a5b87b4a57aa2a4a20c55c9e96a3a305a8143c45" +checksum = "8309d8fc22fc389d831390473b0ee9fe94e85f19a8b9229b9aec8aa73f5bcee3" dependencies = [ "arr_macro", "bit-vec 0.6.3", @@ -2370,6 +2397,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "handlebars" version = "3.5.5" @@ -4550,9 +4587,9 @@ dependencies = [ [[package]] name = "proof-compression" -version = "0.152.10" +version = "0.152.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40624617ed1535349cf31671a7091703d3a31e64d6a7760a5e952c68ee1f4f0e" +checksum = "de4c8014afcd29bfe93ac3bd1ea0d9f2da06fa9895337bead3f3d0d904080e36" dependencies = [ "bincode", "byteorder", @@ -4562,6 +4599,7 @@ dependencies = [ "serde", "serde_json", "shivini", + "zksync-gpu-prover", ] [[package]] @@ -4705,7 +4743,7 @@ dependencies = [ [[package]] name = "prover_cli" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "assert_cmd", @@ -4738,7 +4776,7 @@ dependencies = [ [[package]] name = "prover_version" -version = "0.1.0" +version = "18.0.0" dependencies = [ "zksync_prover_fri_types", ] @@ -4945,6 +4983,12 @@ dependencies = [ "regex-syntax 0.8.5", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.6.29" @@ -5070,9 +5114,9 @@ dependencies = [ [[package]] name = "rescue_poseidon" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c250446885c257bee70bc0f2600229ce72f03073b87fb8f5dd278dba16b11f30" +checksum = "5e631fd184b6d2f2c04f9dc75405289d99fd0d6612d8dfbb478c01bfbab648fb" dependencies = [ "addchain", "arrayvec 0.7.6", @@ -5860,9 +5904,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "shivini" -version = "0.152.10" +version = "0.152.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c336213e4ec7651d2984e892326d09c195ee166493c192b0d8aad36288e5c5f" +checksum = "8937f1fe25a1ea33a40bdf560847b934fe68322c40cd54dd77ab433128022cce" dependencies = [ "bincode", "boojum", @@ -5951,9 +5995,9 @@ dependencies = [ [[package]] name = "snark_wrapper" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f361c2c47b71ee43f62954ce69f7730e14acb7fb3b0f2c697da02f97327c569" +checksum = "eddb498315057210abd25e2fbe2ea30ab69a07ca0c166406a3e7c056ec8fbbfd" dependencies = [ "derivative", "rand 0.4.6", @@ -7839,9 +7883,9 @@ dependencies = [ [[package]] name = "zk_evm" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ee848aa90ae045457795b1c0afeb388fbd9fa1e57aa0e8791b28f405e7cc2c" +checksum = "f11d0310228af78e804e5e7deccd1ad6797fce1c44c3b8016722ab78dc183c4a" dependencies = [ "anyhow", "lazy_static", @@ -7849,7 +7893,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 0.150.19", + "zk_evm_abstractions 0.150.20", ] [[package]] @@ -7880,22 +7924,22 @@ dependencies = [ [[package]] name = "zk_evm_abstractions" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f08feaa3e3d99e1e57234fe6ba2aa062609492c6499b2344121c4a699292ab7" +checksum = "d7616edbdeeeb214211e9bdc4346b6a62c6c6118c3d2b83b7db24c01f65f6e25" dependencies = [ "anyhow", "num_enum 0.6.1", "serde", "static_assertions", - "zkevm_opcode_defs 0.150.19", + "zkevm_opcode_defs 0.150.20", ] [[package]] name = "zkevm-assembly" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd4bc83f3a711d820829dccce24fa59ab4c588c2745203ec6a6ad8c871362b7" +checksum = "c2dc9539ce7f550231934e6b1faae23387fd132f1ac053b8e674d30968158bff" dependencies = [ "env_logger 0.9.3", "hex", @@ -7908,14 +7952,14 @@ dependencies = [ "smallvec", "structopt", "thiserror 1.0.69", - "zkevm_opcode_defs 0.150.19", + "zkevm_opcode_defs 0.150.20", ] [[package]] name = "zkevm_circuits" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760cfbbce18f42bbecd2565de9bf658234cac2431cce9b0c1df08e9df645d467" +checksum = "6f36004572f5086c513715e11f38230e2538c159d4f5d90dc518833c6fc78293" dependencies = [ "arrayvec 0.7.6", "boojum", @@ -7927,7 +7971,7 @@ dependencies = [ "seq-macro", "serde", "smallvec", - "zkevm_opcode_defs 0.150.19", + "zkevm_opcode_defs 0.150.20", "zksync_cs_derive", ] @@ -7975,9 +8019,9 @@ dependencies = [ [[package]] name = "zkevm_opcode_defs" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2bd8ef52c8f9911dd034b91d29f087ab52f80a80f9d996deb881abbb953793" +checksum = "ce6b4a47c0e7f95b51d29ca336821321cec4bbba0acdd412c3a209270a0d37fe" dependencies = [ "bitflags 2.6.0", "blake2 0.10.6", @@ -7992,9 +8036,9 @@ dependencies = [ [[package]] name = "zkevm_test_harness" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24b28c5b855e4e28d85455b48f346e9d46a00c6af84d5bbc38e5b5f7410b5cb" +checksum = "36ed8dd80455d90a51a6618a5bc07685beaad582cabca71ccef25866cd73993b" dependencies = [ "bincode", "circuit_definitions", @@ -8020,9 +8064,9 @@ dependencies = [ [[package]] name = "zksync-gpu-ffi" -version = "0.152.10" +version = "0.152.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f6a84e4e361977a2dc5dbe783e3856e40b1050dc1b9bb3e9833a5e59c20697" +checksum = "6c3fbd4c8df140131d28b05581b19418bc5e561beb21dec6f24ca2f34343399c" dependencies = [ "cmake", "crossbeam", @@ -8035,9 +8079,9 @@ dependencies = [ [[package]] name = "zksync-gpu-prover" -version = "0.152.10" +version = "0.152.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba58bbaf4920c635553d3dfb7796636223f55e75ae6512eb9c98f48f0a03215" +checksum = "0256175ceb3ea675d4c0ebcd690fdd45138bab1c5bc298b2e0db320e5abc0bdb" dependencies = [ "bit-vec 0.6.3", "cfg-if", @@ -8052,9 +8096,9 @@ dependencies = [ [[package]] name = "zksync-wrapper-prover" -version = "0.152.10" +version = "0.152.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4bcf41946f95a1e64ce99cde1d54966a04c5ef2c89d9a87f0fa61e39987510b" +checksum = "390d8f99cf47fade7f2fe38925f9787b3d27641a878887ae980e4ab5f6731ac0" dependencies = [ "circuit_definitions", "zkevm_test_harness", @@ -8063,7 +8107,7 @@ dependencies = [ [[package]] name = "zksync_basic_types" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "chrono", @@ -8084,9 +8128,9 @@ dependencies = [ [[package]] name = "zksync_bellman" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06d424f7e3862d7a6715179bafffbe7a5dce17129f95ac4124502ab9f1edfb8" +checksum = "78fc3c598daf718b6fc791bfbb01c4634199e479ea9b2c82d06cd108b967d441" dependencies = [ "arrayvec 0.7.6", "bit-vec 0.6.3", @@ -8107,7 +8151,7 @@ dependencies = [ [[package]] name = "zksync_circuit_prover" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", @@ -8137,7 +8181,7 @@ dependencies = [ [[package]] name = "zksync_circuit_prover_service" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", @@ -8157,9 +8201,9 @@ dependencies = [ [[package]] name = "zksync_concurrency" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8312ab73d3caa55775bd531795b507fa8f76bd9dabfaeb0954fe43e8fc1323b" +checksum = "cec98400a9e8ba02bfd029eacfe7d6fb7b85b8ef00de59d6bb119d29cc9f7442" dependencies = [ "anyhow", "once_cell", @@ -8176,7 +8220,7 @@ dependencies = [ [[package]] name = "zksync_config" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "rand 0.8.5", @@ -8192,9 +8236,9 @@ dependencies = [ [[package]] name = "zksync_consensus_crypto" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b539960de98df3c3bd27d2d9b97de862027686bbb3bdfc5aaad5b74bb929a1" +checksum = "c04840825dfbe3b9f708d245c87618d5dcf28f29d7b58922971351068a0b8231" dependencies = [ "anyhow", "blst", @@ -8213,9 +8257,9 @@ dependencies = [ [[package]] name = "zksync_consensus_roles" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49949546895a10431b9daec6ec4208ef0917ace006446d304b51f5b234ba462" +checksum = "05498eab1de26869028b5822cfa4490cac625508d427d59668dc73e8162de65f" dependencies = [ "anyhow", "bit-vec 0.6.3", @@ -8235,9 +8279,9 @@ dependencies = [ [[package]] name = "zksync_consensus_storage" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb0d6a54e7d8d2adeee4ba38662161e9309180ad497299092e5641db9fb1c1e" +checksum = "b20eb99fdd0e171a370214d2b7c99b5d4e8c11b9828a6b5705423bf653849a70" dependencies = [ "anyhow", "async-trait", @@ -8255,9 +8299,9 @@ dependencies = [ [[package]] name = "zksync_consensus_utils" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723e2a4b056cc5af192a83163c89a6951ee75c098cc5c4a4cdc435f4232d88bd" +checksum = "f2f9fa69ef68e6a1955a1d7b33077103fb6d106b560fec0d599c6de268f5be03" dependencies = [ "anyhow", "rand 0.8.5", @@ -8267,7 +8311,7 @@ dependencies = [ [[package]] name = "zksync_contracts" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "envy", "hex", @@ -8280,7 +8324,7 @@ dependencies = [ [[package]] name = "zksync_core_leftovers" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "ctrlc", @@ -8294,7 +8338,7 @@ dependencies = [ [[package]] name = "zksync_crypto_primitives" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "blake2 0.10.6", @@ -8310,9 +8354,9 @@ dependencies = [ [[package]] name = "zksync_cs_derive" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23237b019a469bfa59c11108beff84a63a43f52fa3afbf1b461527031fc47644" +checksum = "97ab7469afcd9e1cb220fe17b3c9f2abe031648b94add97da37065c58be08554" dependencies = [ "proc-macro-error", "proc-macro2 1.0.92", @@ -8322,7 +8366,7 @@ dependencies = [ [[package]] name = "zksync_dal" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "bigdecimal", @@ -8332,6 +8376,7 @@ dependencies = [ "itertools 0.10.5", "prost 0.12.6", "rand 0.8.5", + "rayon", "serde", "serde_json", "sqlx", @@ -8357,7 +8402,7 @@ dependencies = [ [[package]] name = "zksync_db_connection" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "rand 0.8.5", @@ -8373,7 +8418,7 @@ dependencies = [ [[package]] name = "zksync_env_config" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "envy", @@ -8384,7 +8429,7 @@ dependencies = [ [[package]] name = "zksync_eth_client" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "async-trait", "jsonrpsee", @@ -8401,7 +8446,7 @@ dependencies = [ [[package]] name = "zksync_eth_signer" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "async-trait", "rlp", @@ -8412,9 +8457,9 @@ dependencies = [ [[package]] name = "zksync_ff" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5aa518ed0ea7ef737d50de02025f5a593dbb11104b3c1bf5a00f39581b47dc" +checksum = "6583c2db6dc787600879d27ec98d2eb628a757ee41831e54f8be1dae4acc599f" dependencies = [ "byteorder", "hex", @@ -8425,9 +8470,9 @@ dependencies = [ [[package]] name = "zksync_ff_derive" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b43100a1278e2f64820368db8751c2441860ea74ab5749074cf8f864647af" +checksum = "8f62e93dde881d8dd44d1864c7682394dde6d18e582fc5af78768221a1766fdf" dependencies = [ "num-bigint 0.4.6", "num-integer", @@ -8440,9 +8485,9 @@ dependencies = [ [[package]] name = "zksync_kzg" -version = "0.150.19" +version = "0.150.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9da880b8282a97d9dfd6ac9f0189d310c0602059a8de20aa66a883979d6adba" +checksum = "174f82592590901cbcf2b298059c89f817b404299ffbd050a3915ea72357f545" dependencies = [ "boojum", "derivative", @@ -8457,7 +8502,7 @@ dependencies = [ [[package]] name = "zksync_l1_contract_interface" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "circuit_definitions", @@ -8474,7 +8519,7 @@ dependencies = [ [[package]] name = "zksync_mini_merkle_tree" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "once_cell", "zksync_basic_types", @@ -8483,7 +8528,7 @@ dependencies = [ [[package]] name = "zksync_multivm" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "circuit_sequencer_api", @@ -8498,7 +8543,7 @@ dependencies = [ "zk_evm 0.133.0", "zk_evm 0.140.0", "zk_evm 0.141.0", - "zk_evm 0.150.19", + "zk_evm 0.150.20", "zksync_contracts", "zksync_mini_merkle_tree", "zksync_system_constants", @@ -8509,7 +8554,7 @@ dependencies = [ [[package]] name = "zksync_object_store" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -8532,9 +8577,9 @@ dependencies = [ [[package]] name = "zksync_pairing" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f0d96f3e386f3b4c76a614d73b71714d6712e917d462bf8053b8af352da0b3" +checksum = "baafdd03ca7a48dc9b6808be3630f2d8a003aa425d71946e9158d8c0aeb1cc79" dependencies = [ "byteorder", "cfg-if", @@ -8545,7 +8590,7 @@ dependencies = [ [[package]] name = "zksync_proof_fri_compressor" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", @@ -8582,9 +8627,9 @@ dependencies = [ [[package]] name = "zksync_protobuf" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8986ad796f8e00d8999fee72effba1a21bce40f5f877d681ac9cd89a94834d8" +checksum = "d9032e12528c2466293b206d6edb53b7e900e4a4cc4573e4d075ac2dc00e1b55" dependencies = [ "anyhow", "bit-vec 0.6.3", @@ -8603,9 +8648,9 @@ dependencies = [ [[package]] name = "zksync_protobuf_build" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d870b31995e3acb8e47afeb68ebeeffcf6121e70020e65b3d5d31692115d236" +checksum = "7c644fc8ef3c4d343ea42cebd5551e3562933f15dd9b0e68a52c2657603eb0f5" dependencies = [ "anyhow", "heck 0.5.0", @@ -8620,7 +8665,7 @@ dependencies = [ [[package]] name = "zksync_protobuf_config" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "hex", @@ -8640,7 +8685,7 @@ dependencies = [ [[package]] name = "zksync_prover_autoscaler" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", @@ -8677,7 +8722,7 @@ dependencies = [ [[package]] name = "zksync_prover_dal" -version = "0.1.0" +version = "18.0.0" dependencies = [ "sqlx", "strum", @@ -8687,7 +8732,7 @@ dependencies = [ [[package]] name = "zksync_prover_fri" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", @@ -8721,7 +8766,7 @@ dependencies = [ [[package]] name = "zksync_prover_fri_gateway" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", @@ -8747,7 +8792,7 @@ dependencies = [ [[package]] name = "zksync_prover_fri_types" -version = "0.1.0" +version = "18.0.0" dependencies = [ "circuit_definitions", "serde", @@ -8757,7 +8802,7 @@ dependencies = [ [[package]] name = "zksync_prover_fri_utils" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "regex", @@ -8775,7 +8820,7 @@ dependencies = [ [[package]] name = "zksync_prover_interface" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "chrono", "circuit_definitions", @@ -8784,6 +8829,7 @@ dependencies = [ "serde", "serde_with", "strum", + "zksync_bellman", "zksync_object_store", "zksync_types", "zksync_vm_interface", @@ -8791,7 +8837,7 @@ dependencies = [ [[package]] name = "zksync_prover_job_monitor" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", @@ -8813,7 +8859,7 @@ dependencies = [ [[package]] name = "zksync_prover_job_processor" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", @@ -8828,7 +8874,7 @@ dependencies = [ [[package]] name = "zksync_prover_keystore" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "bincode", @@ -8841,6 +8887,7 @@ dependencies = [ "hex", "md5", "once_cell", + "proof-compression", "serde", "serde_json", "sha3 0.10.8", @@ -8855,7 +8902,7 @@ dependencies = [ [[package]] name = "zksync_queued_job_processor" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -8867,9 +8914,9 @@ dependencies = [ [[package]] name = "zksync_solidity_vk_codegen" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb10f377dcc24fe2268cc5f530c16af1c879a791570d8fe64064b58ba143c7cc" +checksum = "bb05a12f5552d7947427f755e29f548ce94733851f1fa16edaf8b75c28033e73" dependencies = [ "ethereum-types", "franklin-crypto", @@ -8884,7 +8931,7 @@ dependencies = [ [[package]] name = "zksync_system_constants" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "once_cell", "zksync_basic_types", @@ -8892,13 +8939,14 @@ dependencies = [ [[package]] name = "zksync_types" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", "bigdecimal", "blake2 0.10.6", "chrono", + "ciborium", "derive_more", "hex", "itertools 0.10.5", @@ -8924,7 +8972,7 @@ dependencies = [ [[package]] name = "zksync_utils" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "futures 0.3.31", @@ -8939,7 +8987,7 @@ dependencies = [ [[package]] name = "zksync_vk_setup_data_generator_server_fri" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "bincode", @@ -8963,7 +9011,7 @@ dependencies = [ [[package]] name = "zksync_vlog" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "chrono", @@ -8993,8 +9041,8 @@ source = "git+https://github.com/matter-labs/vm2.git?rev=457d8a7eea9093af9440662 dependencies = [ "enum_dispatch", "primitive-types", - "zk_evm_abstractions 0.150.19", - "zkevm_opcode_defs 0.150.19", + "zk_evm_abstractions 0.150.20", + "zkevm_opcode_defs 0.150.20", "zksync_vm2_interface", ] @@ -9008,7 +9056,7 @@ dependencies = [ [[package]] name = "zksync_vm_interface" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -9024,7 +9072,7 @@ dependencies = [ [[package]] name = "zksync_web3_decl" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", @@ -9045,7 +9093,7 @@ dependencies = [ [[package]] name = "zksync_witness_generator" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", @@ -9083,7 +9131,7 @@ dependencies = [ [[package]] name = "zksync_witness_vector_generator" -version = "0.1.0" +version = "18.0.0" dependencies = [ "anyhow", "async-trait", diff --git a/prover/Cargo.toml b/prover/Cargo.toml index aed8cbfdc723..7144b3821215 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -4,7 +4,7 @@ members = ["crates/bin/*", "crates/lib/*"] resolver = "2" [workspace.package] -version = "0.1.0" +version = "18.0.0" # x-release-please-version edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -67,22 +67,21 @@ tracing-test = "0.2.5" url = "2.5.2" vise = "0.2.0" -# Proving dependencies -circuit_definitions = "=0.150.19" -circuit_sequencer_api = "=0.150.19" -zkevm_test_harness = "=0.150.19" -proof-compression-gpu = { package = "proof-compression", version = "=0.152.10"} -fflonk-gpu = { package = "fflonk-cuda", version = "=0.152.10"} -fflonk = "=0.30.12" -franklin-crypto = "=0.30.12" +circuit_definitions = "=0.150.20" +circuit_sequencer_api = "=0.150.20" +zkevm_test_harness = "=0.150.20" +fflonk = "=0.30.13" +franklin-crypto = "=0.30.13" # GPU proving dependencies -wrapper_prover = { package = "zksync-wrapper-prover", version = "=0.152.10"} -shivini = "=0.152.10" -boojum-cuda = "=0.152.10" +proof-compression-gpu = { package = "proof-compression", version = "=0.152.11"} +fflonk-gpu = { package = "fflonk-cuda", version = "=0.152.11"} +wrapper_prover = { package = "zksync-wrapper-prover", version = "=0.152.11"} +shivini = "=0.152.11" +boojum-cuda = "=0.152.11" # Core workspace dependencies -zksync_multivm = { path = "../core/lib/multivm", version = "0.1.0" } +zksync_multivm = { path = "../core/lib/multivm" } zksync_vlog = { path = "../core/lib/vlog" } zksync_basic_types = { path = "../core/lib/basic_types" } zksync_config = { path = "../core/lib/config" } @@ -98,18 +97,17 @@ zksync_utils = { path = "../core/lib/utils" } zksync_eth_client = { path = "../core/lib/eth_client" } zksync_contracts = { path = "../core/lib/contracts" } zksync_core_leftovers = { path = "../core/lib/zksync_core_leftovers" } -zksync_periodic_job = { path = "../core/lib/periodic_job" } zksync_protobuf_config = { path = "../core/lib/protobuf_config" } # Prover workspace dependencies -zksync_prover_dal = { path = "crates/lib/prover_dal" } -zksync_prover_fri_types = { path = "crates/lib/prover_fri_types" } -zksync_prover_fri_utils = { path = "crates/lib/prover_fri_utils" } -zksync_prover_keystore = { path = "crates/lib/keystore" } -zksync_vk_setup_data_generator_server_fri = { path = "crates/bin/vk_setup_data_generator_server_fri" } -zksync_prover_job_processor = { path = "crates/lib/prover_job_processor" } -zksync_circuit_prover_service = { path = "crates/lib/circuit_prover_service" } -zksync_prover_job_monitor = { path = "crates/bin/prover_job_monitor" } +zksync_prover_dal = { version = "18.0.0", path = "crates/lib/prover_dal" } +zksync_prover_fri_types = { version = "18.0.0", path = "crates/lib/prover_fri_types" } +zksync_prover_fri_utils = { version = "18.0.0", path = "crates/lib/prover_fri_utils" } +zksync_prover_keystore = { version = "18.0.0", path = "crates/lib/keystore" } +zksync_vk_setup_data_generator_server_fri = { version = "18.0.0", path = "crates/bin/vk_setup_data_generator_server_fri" } +zksync_prover_job_processor = { version = "18.0.0", path = "crates/lib/prover_job_processor" } +zksync_circuit_prover_service = { version = "18.0.0", path = "crates/lib/circuit_prover_service" } +zksync_prover_job_monitor = { version = "18.0.0", path = "crates/bin/prover_job_monitor" } # for `perf` profiling [profile.perf] diff --git a/prover/crates/bin/proof_fri_compressor/src/compressor.rs b/prover/crates/bin/proof_fri_compressor/src/compressor.rs index 3671fa183b5d..581e1fed8a48 100644 --- a/prover/crates/bin/proof_fri_compressor/src/compressor.rs +++ b/prover/crates/bin/proof_fri_compressor/src/compressor.rs @@ -2,27 +2,14 @@ use std::{sync::Arc, time::Instant}; use anyhow::Context as _; use async_trait::async_trait; -use circuit_sequencer_api::proof::FinalProof; -use fflonk_gpu::{FflonkSnarkVerifierCircuit, FflonkSnarkVerifierCircuitProof}; +use proof_compression_gpu::{run_proof_chain, SnarkWrapper, SnarkWrapperProof}; use tokio::task::JoinHandle; -use wrapper_prover::{GPUWrapperConfigs, WrapperProver}; -use zkevm_test_harness::proof_wrapper_utils::{get_trusted_setup, DEFAULT_WRAPPER_CONFIG}; use zksync_object_store::ObjectStore; use zksync_prover_dal::{ConnectionPool, Prover, ProverDal}; use zksync_prover_fri_types::{ circuit_definitions::{ boojum::field::goldilocks::GoldilocksField, - circuit_definitions::{ - aux_layer::{ - wrapper::ZkSyncCompressionWrapper, ZkSyncCompressionForWrapperCircuit, - ZkSyncCompressionLayerCircuit, ZkSyncCompressionProof, - ZkSyncCompressionProofForWrapper, ZkSyncCompressionVerificationKeyForWrapper, - }, - recursion_layer::{ - ZkSyncRecursionLayerProof, ZkSyncRecursionLayerStorageType, - ZkSyncRecursionVerificationKey, - }, - }, + circuit_definitions::recursion_layer::ZkSyncRecursionLayerProof, zkevm_circuits::scheduler::block_header::BlockAuxilaryOutputWitness, }, get_current_pod_name, AuxOutputWitnessWrapper, FriProofWrapper, @@ -39,23 +26,16 @@ use crate::metrics::METRICS; pub struct ProofCompressor { blob_store: Arc, pool: ConnectionPool, - compression_mode: u8, max_attempts: u32, protocol_version: ProtocolSemanticVersion, keystore: Keystore, is_fflonk: bool, } -pub enum Proof { - Plonk(Box), - Fflonk(FflonkSnarkVerifierCircuitProof), -} - impl ProofCompressor { pub fn new( blob_store: Arc, pool: ConnectionPool, - compression_mode: u8, max_attempts: u32, protocol_version: ProtocolSemanticVersion, keystore: Keystore, @@ -64,7 +44,6 @@ impl ProofCompressor { Self { blob_store, pool, - compression_mode, max_attempts, protocol_version, keystore, @@ -85,151 +64,6 @@ impl ProofCompressor { } array } - - #[tracing::instrument(skip(proof, _compression_mode))] - pub fn generate_plonk_proof( - proof: ZkSyncRecursionLayerProof, - _compression_mode: u8, - keystore: Keystore, - ) -> anyhow::Result { - let scheduler_vk = keystore - .load_recursive_layer_verification_key( - ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8, - ) - .context("get_recursiver_layer_vk_for_circuit_type()")?; - - let wrapper_proof = { - let crs = get_trusted_setup(); - let wrapper_config = DEFAULT_WRAPPER_CONFIG; - let mut prover = WrapperProver::::new(&crs, wrapper_config).unwrap(); - - prover - .generate_setup_data(scheduler_vk.into_inner()) - .unwrap(); - prover.generate_proofs(proof.into_inner()).unwrap(); - - prover.get_wrapper_proof().unwrap() - }; - - // (Re)serialization should always succeed. - let serialized = bincode::serialize(&wrapper_proof) - .expect("Failed to serialize proof with ZkSyncSnarkWrapperCircuit"); - - // For sending to L1, we can use the `FinalProof` type, that has a generic circuit inside, that is not used for serialization. - // So `FinalProof` and `Proof>>` are compatible on serialization bytecode level. - let final_proof: FinalProof = - bincode::deserialize(&serialized).expect("Failed to deserialize final proof"); - Ok(final_proof) - } - - #[tracing::instrument(skip(proof, compression_mode, keystore))] - pub fn generate_fflonk_proof( - proof: ZkSyncRecursionLayerProof, - compression_mode: u8, - keystore: Keystore, - ) -> anyhow::Result { - let scheduler_vk = keystore - .load_recursive_layer_verification_key( - ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8, - ) - .context("get_recursiver_layer_vk_for_circuit_type()")?; - - // compress proof step by step: 1 -> 2 -> 3 -> 4 -> 5(wrapper) - let (compression_wrapper_proof, compression_wrapper_vk) = Self::compress_proof( - &keystore, - proof.into_inner(), - scheduler_vk.into_inner(), - compression_mode, - )?; - - // construct fflonk snark verifier circuit - let wrapper_function = - ZkSyncCompressionWrapper::from_numeric_circuit_type(compression_mode); - let fixed_parameters = compression_wrapper_vk.fixed_parameters.clone(); - let circuit = FflonkSnarkVerifierCircuit { - witness: Some(compression_wrapper_proof), - vk: compression_wrapper_vk, - fixed_parameters, - transcript_params: (), - wrapper_function, - }; - - tracing::info!("Proving FFLONK snark verifier"); - - let setup = keystore.load_fflonk_snark_verifier_setup_data()?; - - tracing::info!("Loaded setup data for FFLONK verification"); - - let proof = fflonk_gpu::gpu_prove_fflonk_snark_verifier_circuit_with_precomputation( - &circuit, - &setup, - &setup.get_verification_key(), - ); - tracing::info!("Finished proof generation"); - Ok(proof) - } - - pub fn compress_proof( - keystore: &Keystore, - proof: ZkSyncCompressionProof, - vk: ZkSyncRecursionVerificationKey, - compression_steps: u8, - ) -> anyhow::Result<( - ZkSyncCompressionProofForWrapper, - ZkSyncCompressionVerificationKeyForWrapper, - )> { - let worker = franklin_crypto::boojum::worker::Worker::new(); - let mut compression_circuit = - ZkSyncCompressionLayerCircuit::from_witness_and_vk(Some(proof), vk.clone(), 1); - let mut compression_wrapper_circuit = None; - - for step_idx in 1..compression_steps { - tracing::info!("Proving compression {:?}", step_idx); - let setup_data = keystore.load_compression_setup_data(step_idx)?; - let (proof, vk) = - proof_compression_gpu::prove_compression_layer_circuit_with_precomputations( - compression_circuit.clone(), - &setup_data.setup, - setup_data.finalization_hint, - setup_data.vk, - &worker, - ); - tracing::info!("Proof for compression {:?} is generated!", step_idx); - - if step_idx + 1 == compression_steps { - compression_wrapper_circuit = - Some(ZkSyncCompressionForWrapperCircuit::from_witness_and_vk( - Some(proof), - vk, - compression_steps, - )); - } else { - compression_circuit = ZkSyncCompressionLayerCircuit::from_witness_and_vk( - Some(proof), - vk, - step_idx + 1, - ); - } - } - - // last wrapping step - tracing::info!("Proving compression {} for wrapper", compression_steps); - - let setup_data = keystore.load_compression_wrapper_setup_data(compression_steps)?; - let (proof, vk) = - proof_compression_gpu::prove_compression_wrapper_circuit_with_precomputations( - compression_wrapper_circuit.unwrap(), - &setup_data.setup, - setup_data.finalization_hint, - setup_data.vk, - &worker, - ); - tracing::info!( - "Proof for compression wrapper {} is generated!", - compression_steps - ); - Ok((proof, vk)) - } } #[async_trait] @@ -237,7 +71,7 @@ impl JobProcessor for ProofCompressor { type Job = ZkSyncRecursionLayerProof; type JobId = L1BatchNumber; - type JobArtifacts = Proof; + type JobArtifacts = SnarkWrapperProof; const SERVICE_NAME: &'static str = "ProofCompressor"; @@ -292,23 +126,19 @@ impl JobProcessor for ProofCompressor { job: ZkSyncRecursionLayerProof, _started_at: Instant, ) -> JoinHandle> { - let compression_mode = self.compression_mode; let keystore = self.keystore.clone(); - let is_fflonk = self.is_fflonk; + let snark_wrapper_mode = if self.is_fflonk { + SnarkWrapper::FFfonk + } else { + SnarkWrapper::Plonk + }; + tokio::task::spawn_blocking(move || { - if !is_fflonk { - Ok(Proof::Plonk(Box::new(Self::generate_plonk_proof( - job, - compression_mode, - keystore, - )?))) - } else { - Ok(Proof::Fflonk(Self::generate_fflonk_proof( - job, - compression_mode, - keystore, - )?)) - } + Ok(run_proof_chain( + snark_wrapper_mode, + &keystore, + job.into_inner(), + )) }) } @@ -333,16 +163,18 @@ impl JobProcessor for ProofCompressor { Self::aux_output_witness_to_array(aux_output_witness_wrapper.0); let l1_batch_proof = match artifacts { - Proof::Plonk(proof) => L1BatchProofForL1::Plonk(PlonkL1BatchProofForL1 { - aggregation_result_coords, - scheduler_proof: *proof, - protocol_version: self.protocol_version, - }), - Proof::Fflonk(proof) => L1BatchProofForL1::Fflonk(FflonkL1BatchProofForL1 { + SnarkWrapperProof::Plonk(proof) => L1BatchProofForL1::Plonk(PlonkL1BatchProofForL1 { aggregation_result_coords, scheduler_proof: proof, protocol_version: self.protocol_version, }), + SnarkWrapperProof::FFfonk(proof) => { + L1BatchProofForL1::Fflonk(FflonkL1BatchProofForL1 { + aggregation_result_coords, + scheduler_proof: proof, + protocol_version: self.protocol_version, + }) + } }; let blob_save_started_at = Instant::now(); diff --git a/prover/crates/bin/proof_fri_compressor/src/main.rs b/prover/crates/bin/proof_fri_compressor/src/main.rs index dae03ab41465..bb46c1e7cb75 100644 --- a/prover/crates/bin/proof_fri_compressor/src/main.rs +++ b/prover/crates/bin/proof_fri_compressor/src/main.rs @@ -1,7 +1,7 @@ #![allow(incomplete_features)] // We have to use generic const exprs. #![feature(generic_const_exprs)] -use std::{env, time::Duration}; +use std::time::Duration; use anyhow::Context as _; use clap::Parser; @@ -96,7 +96,6 @@ async fn main() -> anyhow::Result<()> { let proof_compressor = ProofCompressor::new( blob_store, pool, - config.compression_mode, config.max_attempts, protocol_version, keystore, @@ -114,7 +113,7 @@ async fn main() -> anyhow::Result<()> { }) .expect("Error setting Ctrl+C handler"); // Setting handler should always succeed. - setup_crs_keys(&config, is_fflonk); + setup_crs_keys(&config); tracing::info!("Starting proof compressor"); @@ -139,20 +138,10 @@ async fn main() -> anyhow::Result<()> { Ok(()) } -fn setup_crs_keys(config: &FriProofCompressorConfig, is_fflonk: bool) { - if is_fflonk { - download_initial_setup_keys_if_not_present( - &config.universal_fflonk_setup_path, - &config.universal_fflonk_setup_download_url, - ); - - env::set_var("COMPACT_CRS_FILE", &config.universal_fflonk_setup_path); - return; - } - +fn setup_crs_keys(config: &FriProofCompressorConfig) { download_initial_setup_keys_if_not_present( &config.universal_setup_path, &config.universal_setup_download_url, ); - env::set_var("CRS_FILE", &config.universal_setup_path); + std::env::set_var("COMPACT_CRS_FILE", &config.universal_setup_path); } diff --git a/prover/crates/bin/prover_cli/src/config/mod.rs b/prover/crates/bin/prover_cli/src/config/mod.rs index b3df2e7d2c56..88cf3a55f908 100644 --- a/prover/crates/bin/prover_cli/src/config/mod.rs +++ b/prover/crates/bin/prover_cli/src/config/mod.rs @@ -6,7 +6,7 @@ pub fn get_envfile() -> anyhow::Result { if let Ok(envfile) = std::env::var("PLI__CONFIG") { return Ok(envfile.into()); } - Ok(Workspace::locate().core().join("etc/pliconfig")) + Ok(Workspace::locate().root().join("etc/pliconfig")) } pub fn load_envfile(path: impl AsRef) -> anyhow::Result<()> { diff --git a/prover/crates/bin/prover_cli/src/helper.rs b/prover/crates/bin/prover_cli/src/helper.rs index 7fe0c990e4e0..b793ce5f2be1 100644 --- a/prover/crates/bin/prover_cli/src/helper.rs +++ b/prover/crates/bin/prover_cli/src/helper.rs @@ -24,7 +24,7 @@ fn read_file_to_json_value(path: &PathBuf) -> serde_json::Value { } fn load_contract_if_present(path: &str) -> Contract { - let path = Workspace::locate().core().join(path); + let path = Workspace::locate().root().join(path); path.exists() .then(|| { serde_json::from_value(read_file_to_json_value(&path)["abi"].take()).unwrap_or_else( diff --git a/prover/crates/bin/vk_setup_data_generator_server_fri/Cargo.toml b/prover/crates/bin/vk_setup_data_generator_server_fri/Cargo.toml index f385c33dd6ad..895d43ae42b7 100644 --- a/prover/crates/bin/vk_setup_data_generator_server_fri/Cargo.toml +++ b/prover/crates/bin/vk_setup_data_generator_server_fri/Cargo.toml @@ -40,4 +40,4 @@ proptest.workspace = true [features] default = [] -gpu = ["zksync_prover_keystore/gpu", "proof-compression-gpu", "shivini"] +gpu = ["zksync_prover_keystore/gpu", "proof-compression-gpu/allocator", "shivini"] diff --git a/prover/crates/bin/vk_setup_data_generator_server_fri/src/main.rs b/prover/crates/bin/vk_setup_data_generator_server_fri/src/main.rs index edd88846d1bc..3e5370b2c888 100644 --- a/prover/crates/bin/vk_setup_data_generator_server_fri/src/main.rs +++ b/prover/crates/bin/vk_setup_data_generator_server_fri/src/main.rs @@ -1,6 +1,5 @@ -#![feature(allocator_api)] -#![allow(dead_code)] // todo: remove after setup is generated -#![allow(unused_imports)] // todo: remove after setup is generated +#![feature(allocator_api, generic_const_exprs)] +#![allow(incomplete_features)] //! Tool to generate different types of keys used by the proving system. //! @@ -12,60 +11,41 @@ use clap::{Parser, Subcommand}; use commitment_generator::read_and_update_contract_toml; use indicatif::{ProgressBar, ProgressStyle}; #[cfg(feature = "gpu")] -use shivini::ProverContext; +use proof_compression_gpu::{ + precompute_proof_chain_with_fflonk, precompute_proof_chain_with_plonk, BlobStorageExt, +}; use tracing::level_filters::LevelFilter; use zkevm_test_harness::{ - boojum::worker::Worker, compute_setups::{ basic_vk_count, generate_base_layer_vks, generate_recursive_layer_vks, recursive_layer_vk_count, }, - data_source::{in_memory_data_source::InMemoryDataSource, SetupDataSource}, - proof_wrapper_utils::{ - check_trusted_setup_file_existace, get_wrapper_setup_and_vk_from_scheduler_vk, - WrapperConfig, - }, -}; -use zksync_prover_fri_types::{ - circuit_definitions::circuit_definitions::recursion_layer::ZkSyncRecursionLayerStorageType, - ProverServiceDataKey, + data_source::in_memory_data_source::InMemoryDataSource, }; -#[cfg(feature = "gpu")] -use zksync_prover_keystore::setup_data_generator::get_fflonk_snark_verifier_setup_and_vk; +use zksync_prover_fri_types::ProverServiceDataKey; use zksync_prover_keystore::{ keystore::Keystore, setup_data_generator::{CPUSetupDataGenerator, GPUSetupDataGenerator, SetupDataGenerator}, }; -#[cfg(feature = "gpu")] -use crate::utils::{ - generate_compression_for_wrapper_vks, generate_compression_vks, - get_plonk_wrapper_setup_and_vk_from_scheduler_vk, -}; - mod commitment_generator; -mod utils; mod vk_commitment_helper; #[cfg(test)] mod tests; + /// Generates new verification keys, and stores them in `keystore`. /// Jobs describe how many generators can run in parallel (each one is around 30 GB). /// If quiet is true, it doesn't display any progress bar. fn generate_vks(keystore: &Keystore, jobs: usize, quiet: bool) -> anyhow::Result<()> { - // Start by checking the trusted setup existence. - // This is used at the last step, but we want to fail early if user didn't configure everything - // correctly. - check_trusted_setup_file_existace(); - let progress_bar = if quiet { None } else { let count = basic_vk_count() + recursive_layer_vk_count() + 2; let progress_bar = ProgressBar::new(count as u64); progress_bar.set_style(ProgressStyle::default_bar() - .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {pos:>7}/{len:7} ({eta})") - .progress_chars("#>-")); + .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {pos:>7}/{len:7} ({eta})") + .progress_chars("#>-")); Some(progress_bar) }; @@ -89,66 +69,7 @@ fn generate_vks(keystore: &Keystore, jobs: usize, quiet: bool) -> anyhow::Result }) .map_err(|err| anyhow::anyhow!("Failed generating recursive vk's: {err}"))?; - #[cfg(feature = "gpu")] - { - let config = WrapperConfig::new(5); - let worker = Worker::new(); - - tracing::info!("Creating prover context"); - - let _context = ProverContext::create().context("failed initializing gpu prover context")?; - tracing::info!("Generating verification keys for compression layers."); - generate_compression_vks(config, &mut in_memory_source, &worker); - - tracing::info!("Generating verification keys for compression for wrapper."); - - generate_compression_for_wrapper_vks(config, &mut in_memory_source, &worker); - - tracing::info!("Saving keys & hints"); - } - - keystore.save_keys_from_data_source(&in_memory_source)?; - - // Generate snark VK - let scheduler_vk = in_memory_source - .get_recursion_layer_vk(ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8) - .map_err(|err| anyhow::anyhow!("Failed to get scheduler vk: {err}"))?; - - tracing::info!("Generating PLONK verification keys for snark wrapper."); - - let (_, plonk_vk) = - get_wrapper_setup_and_vk_from_scheduler_vk(scheduler_vk.clone(), WrapperConfig::new(1)); - - keystore - .save_snark_verification_key(plonk_vk) - .context("save_plonk_snark_vk")?; - - if let Some(p) = pb.lock().unwrap().as_ref() { - p.inc(1) - } - - tracing::info!("PLONK vk is generated"); - - #[cfg(feature = "gpu")] - { - tracing::info!("Generating FFLONK verification keys for snark wrapper."); - - let (_, fflonk_vk) = get_fflonk_snark_verifier_setup_and_vk(&mut in_memory_source); - - keystore - .save_fflonk_snark_verification_key(fflonk_vk) - .context("save_fflonk_snark_vk")?; - - if let Some(p) = pb.lock().unwrap().as_ref() { - p.inc(1) - } - - tracing::info!("FFLONK vk is generated"); - } - - // Let's also update the commitments file. - let commitments = keystore.generate_commitments()?; - keystore.save_commitments(&commitments) + keystore.save_keys_from_data_source(&in_memory_source) } #[derive(Debug, Parser)] @@ -171,9 +92,6 @@ enum CircuitSelector { Recursive, /// Select circuits from basic group. Basic, - Compression, - CompressionWrapper, - Snark, } #[derive(Debug, Parser)] @@ -215,6 +133,10 @@ enum Command { #[arg(long)] quiet: bool, }, + #[command(name = "generate-compressor-data")] + GenerateCompressorPrecomputations, + #[command(name = "generate-crs")] + GenerateCompactCrs, /// Generates setup keys (used by the CPU prover). #[command(name = "generate-sk")] GenerateSetupKeys { @@ -280,17 +202,6 @@ fn generate_setup_keys( .numeric_circuit .expect("--numeric-circuit must be provided"), ), - CircuitSelector::Compression => ProverServiceDataKey::new_compression( - options - .numeric_circuit - .expect("--numeric-circuit must be provided"), - ), - CircuitSelector::CompressionWrapper => ProverServiceDataKey::new_compression_wrapper( - options - .numeric_circuit - .expect("--numeric-circuit must be provided"), - ), - CircuitSelector::Snark => ProverServiceDataKey::snark(), }; let digest = generator @@ -325,7 +236,6 @@ fn main() -> anyhow::Result<()> { read_and_update_contract_toml(&keystore, dryrun) } - Command::GenerateSetupKeys { options } => { let generator = CPUSetupDataGenerator { keystore: keystore_from_optional_path( @@ -344,5 +254,44 @@ fn main() -> anyhow::Result<()> { }; generate_setup_keys(&generator, &options) } + Command::GenerateCompressorPrecomputations => { + #[cfg(not(feature = "gpu"))] + { + anyhow::bail!("Must compile with --gpu feature to use this option.") + } + #[cfg(feature = "gpu")] + { + let keystore = Keystore::locate(); + precompute_proof_chain_with_plonk(&keystore); + precompute_proof_chain_with_fflonk(&keystore); + + let commitments = keystore.generate_commitments()?; + keystore.save_commitments(&commitments) + } + } + Command::GenerateCompactCrs => { + #[cfg(not(feature = "gpu"))] + { + anyhow::bail!("Must compile with --gpu feature to use this option.") + } + #[cfg(feature = "gpu")] + { + let keystore = Keystore::locate(); + + if std::env::var("COMPACT_CRS_FILE").is_err() { + return Err(anyhow::anyhow!("COMPACT_CRS_FILE env variable is not set")); + } + + if std::env::var("IGNITION_TRANSCRIPT_PATH").is_err() { + return Err(anyhow::anyhow!( + "IGNITION_TRANSCRIPT_PATH env variable is not set" + )); + } + + Ok(proof_compression_gpu::create_compact_raw_crs( + keystore.write_compact_raw_crs(), + )) + } + } } } diff --git a/prover/crates/bin/vk_setup_data_generator_server_fri/src/utils.rs b/prover/crates/bin/vk_setup_data_generator_server_fri/src/utils.rs deleted file mode 100644 index 85ce0b5be0b6..000000000000 --- a/prover/crates/bin/vk_setup_data_generator_server_fri/src/utils.rs +++ /dev/null @@ -1,141 +0,0 @@ -use circuit_definitions::{ - boojum::worker::Worker, - circuit_definitions::{ - aux_layer::{ - ZkSyncCompressionForWrapperCircuit, ZkSyncCompressionLayerCircuit, - ZkSyncCompressionLayerStorage, ZkSyncSnarkWrapperSetup, ZkSyncSnarkWrapperVK, - }, - recursion_layer::{ZkSyncRecursionLayerStorageType, ZkSyncRecursionLayerVerificationKey}, - }, -}; -#[cfg(feature = "gpu")] -use shivini::cs::gpu_setup_and_vk_from_base_setup_vk_params_and_hints; -use zkevm_test_harness::{ - data_source::{BlockDataSource, SetupDataSource}, - proof_wrapper_utils::{ - check_trusted_setup_file_existace, get_vk_for_previous_circuit, - get_wrapper_setup_and_vk_from_compression_vk, WrapperConfig, - }, - prover_utils::light::{ - create_light_compression_for_wrapper_setup_data, create_light_compression_layer_setup_data, - }, -}; - -#[cfg(feature = "gpu")] -pub(crate) fn generate_compression_vks( - config: WrapperConfig, - source: &mut DS, - worker: &Worker, -) { - for circuit_type in config.get_compression_types() { - let vk = get_vk_for_previous_circuit(source, circuit_type).unwrap_or_else(|_| { - panic!( - "VK of previous circuit should be present. Current circuit type: {}", - circuit_type - ) - }); - - let compression_circuit = - ZkSyncCompressionLayerCircuit::from_witness_and_vk(None, vk, circuit_type); - let proof_config = compression_circuit.proof_config_for_compression_step(); - - let (setup_base, vk_geometry, vars_hint, witness_hint, finalization_hint) = - create_light_compression_layer_setup_data( - compression_circuit, - worker, - proof_config.fri_lde_factor, - proof_config.merkle_tree_cap_size, - ); - - let (_, vk) = gpu_setup_and_vk_from_base_setup_vk_params_and_hints( - setup_base, - vk_geometry, - vars_hint.clone(), - witness_hint, - worker, - ) - .expect("failed creating GPU compression layer setup data"); - - source - .set_compression_vk(ZkSyncCompressionLayerStorage::from_inner( - circuit_type, - vk.clone(), - )) - .unwrap(); - source - .set_compression_hint(ZkSyncCompressionLayerStorage::from_inner( - circuit_type, - finalization_hint.clone(), - )) - .unwrap(); - } -} - -#[cfg(feature = "gpu")] -pub(crate) fn generate_compression_for_wrapper_vks( - config: WrapperConfig, - source: &mut DS, - worker: &Worker, -) { - let compression_for_wrapper_type = config.get_compression_for_wrapper_type(); - let vk = get_vk_for_previous_circuit(source, compression_for_wrapper_type).unwrap(); - - let circuit = ZkSyncCompressionForWrapperCircuit::from_witness_and_vk( - None, - vk, - compression_for_wrapper_type, - ); - - let proof_config = circuit.proof_config_for_compression_step(); - - let (setup_base, vk_geometry, vars_hint, witness_hint, finalization_hint) = - create_light_compression_for_wrapper_setup_data( - circuit, - worker, - proof_config.fri_lde_factor, - proof_config.merkle_tree_cap_size, - ); - - let (_, vk) = gpu_setup_and_vk_from_base_setup_vk_params_and_hints( - setup_base, - vk_geometry, - vars_hint.clone(), - witness_hint, - worker, - ) - .expect("failed creating GPU compression for wrapper layer setup data"); - - source - .set_compression_for_wrapper_vk(ZkSyncCompressionLayerStorage::from_inner( - compression_for_wrapper_type, - vk.clone(), - )) - .unwrap(); - source - .set_compression_for_wrapper_hint(ZkSyncCompressionLayerStorage::from_inner( - compression_for_wrapper_type, - finalization_hint.clone(), - )) - .unwrap(); -} - -/// Computes wrapper vk from scheduler vk -/// We store all vks in the RAM -pub fn get_plonk_wrapper_setup_and_vk_from_scheduler_vk( - source: &mut DS, - vk: ZkSyncRecursionLayerVerificationKey, - config: WrapperConfig, -) -> (ZkSyncSnarkWrapperSetup, ZkSyncSnarkWrapperVK) { - // Check trusted setup file for later - check_trusted_setup_file_existace(); - - // Check circuit type correctness - assert_eq!( - vk.numeric_circuit_type(), - ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8 - ); - - let wrapper_type = config.get_wrapper_type(); - let wrapper_vk = source.get_compression_for_wrapper_vk(wrapper_type).unwrap(); - get_wrapper_setup_and_vk_from_compression_vk(wrapper_vk, config) -} diff --git a/prover/crates/bin/vk_setup_data_generator_server_fri/src/vk_commitment_helper.rs b/prover/crates/bin/vk_setup_data_generator_server_fri/src/vk_commitment_helper.rs index 2753799dc722..2f5bbf269267 100644 --- a/prover/crates/bin/vk_setup_data_generator_server_fri/src/vk_commitment_helper.rs +++ b/prover/crates/bin/vk_setup_data_generator_server_fri/src/vk_commitment_helper.rs @@ -24,6 +24,6 @@ pub fn read_contract_toml() -> anyhow::Result { pub fn get_contract_toml_path() -> PathBuf { Workspace::locate() - .core() + .root() .join("etc/env/base/contracts.toml") } diff --git a/prover/crates/bin/witness_generator/src/main.rs b/prover/crates/bin/witness_generator/src/main.rs index 8b28ecf3cdd6..b9006341d03c 100644 --- a/prover/crates/bin/witness_generator/src/main.rs +++ b/prover/crates/bin/witness_generator/src/main.rs @@ -104,7 +104,6 @@ async fn main() -> anyhow::Result<()> { let _observability_guard = observability_config.install()?; let started_at = Instant::now(); - let use_push_gateway = opt.batch_size.is_some(); let prover_config = general_config.prover_config.context("prover config")?; let object_store_config = ProverObjectStoreConfig( @@ -121,16 +120,27 @@ async fn main() -> anyhow::Result<()> { let keystore = Keystore::locate().with_setup_path(Some(prover_config.setup_data_path.clone().into())); - let prometheus_config = general_config.prometheus_config.clone(); + let prometheus_config = general_config + .prometheus_config + .context("missing prometheus config")?; - // If the prometheus listener port is not set in the witness generator config, use the one from the prometheus config. - let prometheus_listener_port = if let Some(port) = config.prometheus_listener_port { - port + let prometheus_exporter_config = if prometheus_config.pushgateway_url.is_some() { + let url = prometheus_config + .gateway_endpoint() + .context("missing prometheus gateway endpoint")?; + tracing::info!("Using Prometheus push gateway: {}", url); + PrometheusExporterConfig::push(url, prometheus_config.push_interval()) } else { - prometheus_config - .clone() - .context("prometheus config")? - .listener_port + let prometheus_listener_port = if let Some(port) = config.prometheus_listener_port { + port + } else { + prometheus_config.listener_port + }; + tracing::info!( + "Using Prometheus pull on port: {}", + prometheus_listener_port + ); + PrometheusExporterConfig::pull(prometheus_listener_port) }; let connection_pool = ConnectionPool::::singleton(database_secrets.prover_url()?) @@ -166,20 +176,7 @@ async fn main() -> anyhow::Result<()> { } }; - let prometheus_config = if use_push_gateway { - let prometheus_config = prometheus_config - .clone() - .context("prometheus config needed when use_push_gateway enabled")?; - PrometheusExporterConfig::push( - prometheus_config - .gateway_endpoint() - .context("gateway_endpoint needed when use_push_gateway enabled")?, - prometheus_config.push_interval(), - ) - } else { - PrometheusExporterConfig::pull(prometheus_listener_port as u16) - }; - let prometheus_task = prometheus_config.run(stop_receiver.clone()); + let prometheus_task = prometheus_exporter_config.run(stop_receiver.clone()); let mut tasks = Vec::new(); tasks.push(tokio::spawn(prometheus_task)); diff --git a/prover/crates/bin/witness_generator/src/rounds/mod.rs b/prover/crates/bin/witness_generator/src/rounds/mod.rs index 6fd72c968693..6da6f5bb393d 100644 --- a/prover/crates/bin/witness_generator/src/rounds/mod.rs +++ b/prover/crates/bin/witness_generator/src/rounds/mod.rs @@ -173,6 +173,9 @@ where artifacts, ) .await?; + + tracing::info!("Saved {:?} to database for job {:?}", R::ROUND, job_id); + Ok(()) } diff --git a/prover/crates/lib/circuit_prover_service/Cargo.toml b/prover/crates/lib/circuit_prover_service/Cargo.toml index ca7d1ede02f1..3b152528ab68 100644 --- a/prover/crates/lib/circuit_prover_service/Cargo.toml +++ b/prover/crates/lib/circuit_prover_service/Cargo.toml @@ -13,7 +13,7 @@ categories.workspace = true [dependencies] zksync_prover_job_processor.workspace = true zksync_prover_fri_types.workspace = true -zksync_prover_keystore.workspace = true +zksync_prover_keystore = { workspace = true, features = ["gpu-light"] } zksync_prover_dal.workspace = true zksync_types.workspace = true zksync_object_store.workspace = true @@ -24,8 +24,6 @@ tokio = { workspace = true, features = ["macros", "time"] } tokio-util.workspace = true tracing.workspace = true -shivini = { workspace = true, features = [ - "circuit_definitions", -] } +shivini = { workspace = true, features = ["circuit_definitions"] } zkevm_test_harness.workspace = true vise.workspace = true diff --git a/prover/crates/lib/circuit_prover_service/src/lib.rs b/prover/crates/lib/circuit_prover_service/src/lib.rs index 19e7bb1f41ee..59132e17c1bc 100644 --- a/prover/crates/lib/circuit_prover_service/src/lib.rs +++ b/prover/crates/lib/circuit_prover_service/src/lib.rs @@ -2,8 +2,8 @@ // Crypto code uses generic const exprs, allocator_api is needed to use global allocators #![feature(generic_const_exprs, allocator_api)] -mod gpu_circuit_prover; +pub mod gpu_circuit_prover; pub mod job_runner; mod metrics; -mod types; -mod witness_vector_generator; +pub mod types; +pub mod witness_vector_generator; diff --git a/prover/crates/lib/circuit_prover_service/src/types/circuit.rs b/prover/crates/lib/circuit_prover_service/src/types/circuit.rs index 264daba63b7d..7185c9abbcd2 100644 --- a/prover/crates/lib/circuit_prover_service/src/types/circuit.rs +++ b/prover/crates/lib/circuit_prover_service/src/types/circuit.rs @@ -134,7 +134,7 @@ impl Circuit { /// Synthesize vector for a given circuit. /// Expects finalization hints to match circuit. - pub(crate) fn synthesize_vector( + pub fn synthesize_vector( &self, finalization_hints: Arc, ) -> anyhow::Result> { diff --git a/prover/crates/lib/keystore/Cargo.toml b/prover/crates/lib/keystore/Cargo.toml index a247a24bdd8b..2c21067f2428 100644 --- a/prover/crates/lib/keystore/Cargo.toml +++ b/prover/crates/lib/keystore/Cargo.toml @@ -17,6 +17,7 @@ zkevm_test_harness.workspace = true circuit_definitions = { workspace = true, features = ["log_tracing"] } shivini = { workspace = true, optional = true } fflonk-gpu = { workspace = true, optional = true } +proof-compression-gpu = { workspace = true, optional = true } fflonk.workspace = true boojum-cuda = { workspace = true, optional = true } @@ -37,4 +38,4 @@ futures = { workspace = true, features = ["compat"] } default = [] # feature to not compile era-bellman-cuda, but to be able to use GPU features gpu-light = ["dep:shivini", "dep:boojum-cuda"] -gpu = ["dep:shivini", "dep:fflonk-gpu", "dep:boojum-cuda"] +gpu = ["dep:shivini", "dep:fflonk-gpu", "dep:boojum-cuda", "dep:proof-compression-gpu"] diff --git a/prover/crates/lib/keystore/src/compressor.rs b/prover/crates/lib/keystore/src/compressor.rs new file mode 100644 index 000000000000..ea4518238fd6 --- /dev/null +++ b/prover/crates/lib/keystore/src/compressor.rs @@ -0,0 +1,221 @@ +use std::{ + fs::File, + io::{Read, Write}, +}; + +use circuit_definitions::circuit_definitions::recursion_layer::ZkSyncRecursionLayerStorageType; +use zksync_prover_fri_types::ProverServiceDataKey; + +use crate::keystore::{Keystore, ProverServiceDataType}; + +const COMPACT_CRS_ENV_VAR: &str = "COMPACT_CRS_FILE"; + +impl proof_compression_gpu::BlobStorage for Keystore { + fn read_scheduler_vk(&self) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_recursive( + ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8, + ), + ProverServiceDataType::VerificationKey, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_compression_layer_finalization_hint(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression(circuit_id), + ProverServiceDataType::FinalizationHints, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_compression_layer_vk(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression(circuit_id), + ProverServiceDataType::VerificationKey, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_compression_layer_precomputation(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression(circuit_id), + ProverServiceDataType::SetupData, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_compression_wrapper_finalization_hint(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression_wrapper(circuit_id), + ProverServiceDataType::FinalizationHints, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_compression_wrapper_vk(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression_wrapper(circuit_id), + ProverServiceDataType::VerificationKey, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_compression_wrapper_precomputation( + &self, + circuit_id: u8, + ) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression_wrapper(circuit_id), + ProverServiceDataType::SetupData, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_fflonk_vk(&self) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::snark(), + ProverServiceDataType::FflonkSnarkVerificationKey, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_fflonk_precomputation(&self) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::snark(), + ProverServiceDataType::FflonkSetupData, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_plonk_vk(&self) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::snark(), + ProverServiceDataType::SnarkVerificationKey, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_plonk_precomputation(&self) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::snark(), + ProverServiceDataType::PlonkSetupData, + ); + + Box::new(File::open(filepath).unwrap()) + } + + fn read_compact_raw_crs(&self) -> Box { + let filepath = + std::env::var(COMPACT_CRS_ENV_VAR).expect("No compact CRS file path provided"); + Box::new(File::open(filepath).unwrap()) + } +} + +impl proof_compression_gpu::BlobStorageExt for Keystore { + fn write_compression_layer_finalization_hint(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression(circuit_id), + ProverServiceDataType::FinalizationHints, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_compression_layer_vk(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression(circuit_id), + ProverServiceDataType::VerificationKey, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_compression_layer_precomputation(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression(circuit_id), + ProverServiceDataType::SetupData, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_compression_wrapper_finalization_hint(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression_wrapper(circuit_id), + ProverServiceDataType::FinalizationHints, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_compression_wrapper_vk(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression_wrapper(circuit_id), + ProverServiceDataType::VerificationKey, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_compression_wrapper_precomputation(&self, circuit_id: u8) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::new_compression_wrapper(circuit_id), + ProverServiceDataType::SetupData, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_fflonk_vk(&self) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::snark(), + ProverServiceDataType::FflonkSnarkVerificationKey, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_fflonk_precomputation(&self) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::snark(), + ProverServiceDataType::FflonkSetupData, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_plonk_vk(&self) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::snark(), + ProverServiceDataType::SnarkVerificationKey, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_plonk_precomputation(&self) -> Box { + let filepath = self.get_file_path( + ProverServiceDataKey::snark(), + ProverServiceDataType::PlonkSetupData, + ); + + Box::new(File::create(filepath).unwrap()) + } + + fn write_compact_raw_crs(&self) -> Box { + let filepath = + std::env::var(COMPACT_CRS_ENV_VAR).expect("No compact CRS file path provided"); + Box::new(File::create(filepath).unwrap()) + } +} diff --git a/prover/crates/lib/keystore/src/keystore.rs b/prover/crates/lib/keystore/src/keystore.rs index fb84436916e7..f69e371cac48 100644 --- a/prover/crates/lib/keystore/src/keystore.rs +++ b/prover/crates/lib/keystore/src/keystore.rs @@ -41,6 +41,8 @@ pub enum ProverServiceDataType { VerificationKey, SetupData, FinalizationHints, + PlonkSetupData, + FflonkSetupData, SnarkVerificationKey, FflonkSnarkVerificationKey, } @@ -78,7 +80,7 @@ impl Keystore { // - We're running from the core workspace. // - We're running the binary from the docker. let data_dir_path = match Workspace::locate() { - Workspace::None => { + Workspace::Root => { // We're running a binary, likely in a docker. // Keys can be in one of a few paths. // We want to be very conservative here, and checking @@ -114,7 +116,7 @@ impl Keystore { &self.basedir } - fn get_file_path( + pub(crate) fn get_file_path( &self, key: ProverServiceDataKey, service_data_type: ProverServiceDataType, @@ -130,6 +132,12 @@ impl Keystore { ProverServiceDataType::FinalizationHints => self .basedir .join(format!("finalization_hints_{}.bin", name)), + ProverServiceDataType::PlonkSetupData => self + .setup_data_path + .join(format!("plonk_setup_{}_data.bin", name)), + ProverServiceDataType::FflonkSetupData => self + .setup_data_path + .join(format!("fflonk_setup_{}_data.bin", name)), ProverServiceDataType::SnarkVerificationKey => { self.basedir.join(format!("verification_{}_key.json", name)) } @@ -187,6 +195,14 @@ impl Keystore { &self, circuit_type: u8, ) -> anyhow::Result { + if circuit_type == ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8 { + let vk = Self::load_json_from_file(self.get_file_path( + ProverServiceDataKey::new_recursive(circuit_type), + ProverServiceDataType::VerificationKey, + ))?; + return Ok(ZkSyncRecursionLayerVerificationKey::SchedulerCircuit(vk)); + } + Self::load_json_from_file(self.get_file_path( ProverServiceDataKey::new_recursive(circuit_type), ProverServiceDataType::VerificationKey, @@ -197,20 +213,43 @@ impl Keystore { &self, circuit_type: u8, ) -> anyhow::Result { - Self::load_json_from_file(self.get_file_path( + let key = Self::load_json_from_file(self.get_file_path( ProverServiceDataKey::new_compression(circuit_type), ProverServiceDataType::VerificationKey, - )) + ))?; + + match circuit_type { + 1 => Ok(ZkSyncCompressionLayerVerificationKey::CompressionMode1Circuit(key)), + 2 => Ok(ZkSyncCompressionLayerVerificationKey::CompressionMode2Circuit(key)), + 3 => Ok(ZkSyncCompressionLayerVerificationKey::CompressionMode3Circuit(key)), + 4 => Ok(ZkSyncCompressionLayerVerificationKey::CompressionMode4Circuit(key)), + _ => Err(anyhow::anyhow!( + "Invalid compression circuit type: {}", + circuit_type + )), + } } pub fn load_compression_for_wrapper_vk( &self, circuit_type: u8, ) -> anyhow::Result { - Self::load_json_from_file(self.get_file_path( + let key = Self::load_json_from_file(self.get_file_path( ProverServiceDataKey::new_compression_wrapper(circuit_type), ProverServiceDataType::VerificationKey, - )) + ))?; + + match circuit_type { + 1 => Ok(ZkSyncCompressionForWrapperVerificationKey::CompressionMode1Circuit(key)), + 2 => Ok(ZkSyncCompressionForWrapperVerificationKey::CompressionMode2Circuit(key)), + 3 => Ok(ZkSyncCompressionForWrapperVerificationKey::CompressionMode3Circuit(key)), + 4 => Ok(ZkSyncCompressionForWrapperVerificationKey::CompressionMode4Circuit(key)), + 5 => Ok(ZkSyncCompressionForWrapperVerificationKey::CompressionMode5Circuit(key)), + _ => Err(anyhow::anyhow!( + "Invalid compression circuit type: {}", + circuit_type + )), + } } pub fn save_base_layer_verification_key( @@ -233,6 +272,12 @@ impl Keystore { ProverServiceDataKey::new_recursive(vk.numeric_circuit_type()), ProverServiceDataType::VerificationKey, ); + + if let ZkSyncRecursionLayerVerificationKey::SchedulerCircuit(key) = vk { + tracing::info!("saving recursive layer verification key to: {:?}", filepath); + return Self::save_json_pretty(filepath, &key); + } + tracing::info!("saving recursive layer verification key to: {:?}", filepath); Self::save_json_pretty(filepath, &vk) } @@ -249,7 +294,7 @@ impl Keystore { "saving compression layer verification key to: {:?}", filepath ); - Self::save_json_pretty(filepath, &vk) + Self::save_json_pretty(filepath, &vk.into_inner()) } pub fn save_compression_for_wrapper_vk( @@ -264,7 +309,7 @@ impl Keystore { "saving compression wrapper verification key to: {:?}", filepath ); - Self::save_json_pretty(filepath, &vk) + Self::save_json_pretty(filepath, &vk.into_inner()) } /// @@ -645,45 +690,6 @@ impl Keystore { ) .context("save_finalization_hints()")?; - // Compression - // todo: don't use hardcoded values - for circuit in 1..5 { - let vk = source - .get_compression_vk(circuit as u8) - .map_err(|err| anyhow::anyhow!("No vk exist for circuit type: {circuit}: {err}"))?; - - self.save_compression_vk(vk) - .context("save_compression_vk()")?; - - let hint = source.get_compression_hint(circuit as u8).map_err(|err| { - anyhow::anyhow!("No finalization hint exist for circuit type: {circuit}: {err}") - })?; - - self.save_finalization_hints( - ProverServiceDataKey::new_compression(circuit as u8), - &hint.into_inner(), - ) - .context("save_finalization_hints()")?; - } - - // Compression wrapper - let vk = source - .get_compression_for_wrapper_vk(5) - .map_err(|err| anyhow::anyhow!("No vk exist for circuit type: 5: {err}"))?; - - self.save_compression_for_wrapper_vk(vk) - .context("save_compression_wrapper_vk()")?; - - let hint = source.get_compression_for_wrapper_hint(5).map_err(|err| { - anyhow::anyhow!("No finalization hint exist for circuit type: 5: {err}") - })?; - - self.save_finalization_hints( - ProverServiceDataKey::new_compression_wrapper(5), - &hint.into_inner(), - ) - .context("save_finalization_hints()")?; - Ok(()) } diff --git a/prover/crates/lib/keystore/src/lib.rs b/prover/crates/lib/keystore/src/lib.rs index e5f00fd307ba..bc8bbdcd992c 100644 --- a/prover/crates/lib/keystore/src/lib.rs +++ b/prover/crates/lib/keystore/src/lib.rs @@ -28,6 +28,9 @@ pub mod keystore; pub mod setup_data_generator; pub mod utils; +#[cfg(feature = "gpu")] +pub mod compressor; + #[derive(Debug, Serialize, Deserialize)] #[serde( bound = "F: serde::Serialize + serde::de::DeserializeOwned, P: serde::Serialize + serde::de::DeserializeOwned" diff --git a/prover/crates/lib/keystore/src/setup_data_generator.rs b/prover/crates/lib/keystore/src/setup_data_generator.rs index 162d94ced6dd..ae926d17ca3f 100644 --- a/prover/crates/lib/keystore/src/setup_data_generator.rs +++ b/prover/crates/lib/keystore/src/setup_data_generator.rs @@ -7,21 +7,9 @@ use anyhow::Context as _; #[cfg(any(feature = "gpu", feature = "gpu-light"))] use boojum_cuda::poseidon2::GLHasher; #[cfg(any(feature = "gpu", feature = "gpu-light"))] -use circuit_definitions::circuit_definitions::aux_layer::{ - wrapper::ZkSyncCompressionWrapper, CompressionProofsTreeHasherForWrapper, -}; -#[cfg(feature = "gpu")] -use fflonk_gpu::{ - FflonkDeviceSetup, FflonkSnarkVerifierCircuit, FflonkSnarkVerifierCircuitDeviceSetup, - FflonkSnarkVerifierCircuitVK, -}; -#[cfg(any(feature = "gpu", feature = "gpu-light"))] use shivini::cs::gpu_setup_and_vk_from_base_setup_vk_params_and_hints; #[cfg(any(feature = "gpu", feature = "gpu-light"))] -use zkevm_test_harness::{ - compute_setups::light::generate_light_circuit_setup_data, - data_source::in_memory_data_source::InMemoryDataSource, -}; +use zkevm_test_harness::compute_setups::light::generate_light_circuit_setup_data; use zkevm_test_harness::{ compute_setups::{generate_circuit_setup_data, CircuitSetupData}, data_source::SetupDataSource, @@ -55,10 +43,10 @@ pub fn generate_setup_data_common( .into_inner(), ), ProvingStage::Compression => { - unreachable!("Compression stage should not be generated with CPU.") + unreachable!("Compression stage setup data should be generated with a generate-compressor-data command") } ProvingStage::CompressionWrapper => { - unreachable!("CompressionWrapper stage should not be generated with CPU.") + unreachable!("CompressionWrapper stage setup data should be generated with a generate-compressor-data command") } _ => ( Some(keystore.load_finalization_hints(circuit)?), @@ -108,23 +96,9 @@ pub trait SetupDataGenerator { } if circuit == ProverServiceDataKey::snark() { - #[cfg(not(feature = "gpu"))] - { - anyhow::bail!("Must compile with --gpu feature to use this option."); - } - #[cfg(feature = "gpu")] - { - let mut data_source = self.keystore().load_keys_to_data_source()?; - let (setup, _) = get_fflonk_snark_verifier_setup_and_vk(&mut data_source); - if !dry_run { - self.keystore() - .save_fflonk_snark_setup_data(setup) - .context("save_setup_data()")?; - } - return Ok(String::from( - "FFLONK is serialized differently, skipping hashing.", - )); - } + unreachable!( + "Snark setup data should be generated with generate-compressor-data command" + ) } let serialized = self.generate_setup_data(circuit)?; @@ -146,7 +120,7 @@ pub trait SetupDataGenerator { dry_run: bool, recompute_if_missing: bool, ) -> anyhow::Result> { - Ok(ProverServiceDataKey::all() + Ok(ProverServiceDataKey::all_boojum() .iter() .map(|circuit| { tracing::info!("Generating setup data for {:?}", circuit.name()); @@ -206,44 +180,10 @@ impl SetupDataGenerator for GPUSetupDataGenerator { let worker = Worker::new(); match circuit.stage { - ProvingStage::CompressionWrapper => { - let (gpu_setup_data, verification_key) = - gpu_setup_and_vk_from_base_setup_vk_params_and_hints::< - CompressionProofsTreeHasherForWrapper, - _, - >( - circuit_setup_data.setup_base, - circuit_setup_data.vk_geometry, - circuit_setup_data.vars_hint.clone(), - circuit_setup_data.wits_hint, - &worker, - ) - .context("failed creating GPU base layer setup data")?; - - let gpu_prover_setup_data = GpuProverSetupData { - setup: gpu_setup_data, - vk: verification_key.clone(), - finalization_hint: circuit_setup_data.finalization_hint, - }; - - let serialized_vk = get_vk_by_circuit(self.keystore.clone(), circuit)?; - - assert_eq!( - bincode::serialize(&verification_key) - .expect("Failed serializing setup data"), - serialized_vk, - "Verification key mismatch for circuit: {:?}", - circuit.name() - ); - - // Serialization should always succeed. - Ok(bincode::serialize(&gpu_prover_setup_data) - .expect("Failed serializing setup data")) - } - ProvingStage::Snark => { - unreachable!( - "We cannot serialize Fflonk data with bincode, it is done separately" - ) + ProvingStage::CompressionWrapper + | ProvingStage::Snark + | ProvingStage::Compression => { + unreachable!("Setup data for compression, compression-wrapper and snark stages should be generated with generate-compressor-data command") } _ => { let (gpu_setup_data, verification_key) = @@ -320,31 +260,3 @@ fn get_vk_by_circuit(keystore: Keystore, circuit: ProverServiceDataKey) -> anyho } } } - -#[cfg(feature = "gpu")] -pub fn get_fflonk_snark_verifier_setup_and_vk( - data_source: &mut InMemoryDataSource, -) -> ( - FflonkSnarkVerifierCircuitDeviceSetup, - FflonkSnarkVerifierCircuitVK, -) { - let vk = data_source - .get_compression_for_wrapper_vk(5) - .unwrap() - .into_inner(); - let fixed_parameters = vk.fixed_parameters.clone(); - // todo: do not hardcode this value - let wrapper_function = ZkSyncCompressionWrapper::from_numeric_circuit_type(5); - - let circuit = FflonkSnarkVerifierCircuit { - witness: None, - vk, - fixed_parameters, - transcript_params: (), - wrapper_function, - }; - let setup = FflonkDeviceSetup::<_, _, _>::create_setup_on_device(&circuit).unwrap(); - let snark_vk = setup.get_verification_key(); - - (setup, snark_vk) -} diff --git a/prover/crates/lib/prover_fri_types/src/lib.rs b/prover/crates/lib/prover_fri_types/src/lib.rs index 9d7c32c21d73..5b7a54a31052 100644 --- a/prover/crates/lib/prover_fri_types/src/lib.rs +++ b/prover/crates/lib/prover_fri_types/src/lib.rs @@ -294,12 +294,6 @@ impl ProverServiceDataKey { for numeric_circuit in ZkSyncRecursionLayerStorageType::as_iter_u8() { results.push(ProverServiceDataKey::new_recursive(numeric_circuit)) } - - for numeric_circuit in 1..MAX_COMPRESSION_CIRCUITS { - results.push(ProverServiceDataKey::new_compression(numeric_circuit)); - } - results.push(ProverServiceDataKey::new_compression_wrapper(5)); - results } @@ -311,12 +305,6 @@ impl ProverServiceDataKey { } } - pub fn all() -> Vec { - let mut keys = Self::all_boojum(); - keys.push(Self::snark()); - keys - } - pub fn is_base_layer(&self) -> bool { self.stage == ProvingStage::BasicCircuits } diff --git a/prover/crates/lib/prover_job_processor/Cargo.toml b/prover/crates/lib/prover_job_processor/Cargo.toml index 5197b33b1f95..fea4c6195fd7 100644 --- a/prover/crates/lib/prover_job_processor/Cargo.toml +++ b/prover/crates/lib/prover_job_processor/Cargo.toml @@ -14,7 +14,7 @@ categories.workspace = true async-trait.workspace = true anyhow.workspace = true futures.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["rt"] } tokio-stream.workspace = true tokio-util.workspace = true tracing.workspace = true diff --git a/prover/data/historical_data/0.25.0/commitments.json b/prover/data/historical_data/0.25.0/commitments.json new file mode 100644 index 000000000000..086609a5822b --- /dev/null +++ b/prover/data/historical_data/0.25.0/commitments.json @@ -0,0 +1,6 @@ +{ + "leaf": "0xf9664f4324c1400fa5c3822d667f30e873f53f1b8033180cd15fe41c1e2355c6", + "node": "0xf520cd5b37e74e19fdb369c8d676a04dce8a19457497ac6686d2bb95d94109c8", + "scheduler": "0xe6ba9d6b042440c480fa1c7182be32387db6e90281e82f37398d3f98f63f098a", + "snark_wrapper": "0x14f97b81e54b35fe673d8708cc1a19e1ea5b5e348e12d31e39824ed4f42bbca2" +} \ No newline at end of file diff --git a/prover/data/historical_data/0.25.0/snark_verification_scheduler_key.json b/prover/data/historical_data/0.25.0/snark_verification_scheduler_key.json new file mode 100644 index 000000000000..acb7e3fe8969 --- /dev/null +++ b/prover/data/historical_data/0.25.0/snark_verification_scheduler_key.json @@ -0,0 +1,399 @@ +{ + "n": 16777215, + "num_inputs": 1, + "state_width": 4, + "num_witness_polys": 0, + "gate_setup_commitments": [ + { + "x": [ + 14543631136906534221, + 11532161447842416044, + 11114175029926010938, + 1228896787564295039 + ], + "y": [ + 13293602262342424489, + 8897930584356943159, + 13256028170406220369, + 3214939367598363288 + ], + "infinity": false + }, + { + "x": [ + 11488992528554025682, + 12016824828223971094, + 11942004360057333370, + 316831626296641307 + ], + "y": [ + 304673622018339856, + 7139037552557818730, + 12475560967982555143, + 1055588351918295250 + ], + "infinity": false + }, + { + "x": [ + 2274984630539920017, + 5398167177582250136, + 16440396753384808945, + 1037682586893548769 + ], + "y": [ + 10168660308952593373, + 16526369642614237721, + 569062739734175056, + 155645558476901406 + ], + "infinity": false + }, + { + "x": [ + 14005362797509427677, + 2662603874351919260, + 14261489165672308143, + 1470528288349794782 + ], + "y": [ + 11144229651170108862, + 11439490264313454962, + 114993091474760680, + 1037267173208738614 + ], + "infinity": false + }, + { + "x": [ + 10726125240955612787, + 1916320162213728495, + 1058608086768277905, + 1651114031905829493 + ], + "y": [ + 13237242732587628574, + 4774776044666137690, + 14401013098807103799, + 2514139699916115771 + ], + "infinity": false + }, + { + "x": [ + 14434760601334248377, + 5316938318287831815, + 6221098547630910324, + 980422841280734466 + ], + "y": [ + 9201886393750447942, + 3840149540273146267, + 18179910191622136829, + 1563809864380914603 + ], + "infinity": false + }, + { + "x": [ + 9586697317366528906, + 2325800863365957883, + 1243781259615311278, + 3048012003267036960 + ], + "y": [ + 612821620743617231, + 1510385666449513894, + 9368337288452385056, + 2949736812933507034 + ], + "infinity": false + }, + { + "x": [ + 11830690209042008764, + 11761396005838073769, + 18271188400274886574, + 2896734446482773484 + ], + "y": [ + 1890606551566554401, + 10220931290312275762, + 3256711195869515344, + 2466626485328709457 + ], + "infinity": false + } + ], + "gate_selectors_commitments": [ + { + "x": [ + 10865727529243127085, + 4083978853392244827, + 14303622309482785753, + 2263042021033673595 + ], + "y": [ + 3019601017411802529, + 880444282195426618, + 9998743525359587628, + 2891421025832200233 + ], + "infinity": false + }, + { + "x": [ + 5208608554346323426, + 8575970970223832576, + 2966209169082345602, + 239576408267301488 + ], + "y": [ + 17715084817752316452, + 2726293100894160682, + 17920596859559317135, + 3485576345363305439 + ], + "infinity": false + } + ], + "permutation_commitments": [ + { + "x": [ + 14761045450946573029, + 17157644513453531531, + 2555518804134782053, + 1415819224310783987 + ], + "y": [ + 17265629196749977462, + 4128711855633066822, + 8435602817910411328, + 1408116296902303196 + ], + "infinity": false + }, + { + "x": [ + 3307267823832528482, + 2406249680085831639, + 9091964031261402109, + 2846274000290842933 + ], + "y": [ + 17374905554931807856, + 6690578002079222163, + 11809376320193686210, + 2676076649992974574 + ], + "infinity": false + }, + { + "x": [ + 3159118708748226574, + 5508845413629697013, + 13350869305506486049, + 689297560178790472 + ], + "y": [ + 15696011303896469684, + 12551611148155235140, + 14438660833518031207, + 425021756161657108 + ], + "infinity": false + }, + { + "x": [ + 18349397811516917436, + 4473982696343317918, + 13070312540813307819, + 2109468484629113245 + ], + "y": [ + 13254534552549721008, + 17388411854346636521, + 17875890960520499518, + 1062184221180884481 + ], + "infinity": false + } + ], + "total_lookup_entries_length": 1787472, + "lookup_selector_commitment": { + "x": [ + 9324906502432882695, + 14977861238256290580, + 12538013124354067293, + 3408438202312564138 + ], + "y": [ + 14942105932194201701, + 12210090881357612547, + 14774705021036784261, + 2531694948512337448 + ], + "infinity": false + }, + "lookup_tables_commitments": [ + { + "x": [ + 10873859091125335643, + 3906092213625635374, + 17046157606087980048, + 3193402705223440293 + ], + "y": [ + 10158946293873382504, + 2171386304067884865, + 6918663094168980658, + 350601565475975409 + ], + "infinity": false + }, + { + "x": [ + 12822112641313049260, + 3646552465186399021, + 10324071010773924047, + 2209084192380614662 + ], + "y": [ + 11045141628975531869, + 12589678537679955590, + 3065046617868727674, + 2099447669854151830 + ], + "infinity": false + }, + { + "x": [ + 11395032673621937545, + 3000063650268118516, + 7857619430005721792, + 805706808484810738 + ], + "y": [ + 6817063666434679427, + 1646386051225388537, + 4677946977082722827, + 1369650305976868514 + ], + "infinity": false + }, + { + "x": [ + 2885179371868476351, + 159944842081142878, + 6092294387055034894, + 213843603626505240 + ], + "y": [ + 11868113133779277990, + 8509646480531194854, + 14088068011597639414, + 707070630614027545 + ], + "infinity": false + } + ], + "lookup_table_type_commitment": { + "x": [ + 1732877442096985191, + 7537030715658833452, + 14073502080301311448, + 2178792007727681099 + ], + "y": [ + 8513095304113652904, + 6581396660744182779, + 13939755637576387431, + 2477157044961106453 + ], + "infinity": false + }, + "non_residues": [ + [ + 5, + 0, + 0, + 0 + ], + [ + 7, + 0, + 0, + 0 + ], + [ + 10, + 0, + 0, + 0 + ] + ], + "g2_elements": [ + { + "x": { + "c0": [ + 5106727233969649389, + 7440829307424791261, + 4785637993704342649, + 1729627375292849782 + ], + "c1": [ + 10945020018377822914, + 17413811393473931026, + 8241798111626485029, + 1841571559660931130 + ] + }, + "y": { + "c0": [ + 5541340697920699818, + 16416156555105522555, + 5380518976772849807, + 1353435754470862315 + ], + "c1": [ + 6173549831154472795, + 13567992399387660019, + 17050234209342075797, + 650358724130500725 + ] + }, + "infinity": false + }, + { + "x": { + "c0": [ + 9089143573911733168, + 11482283522806384523, + 13585589533905622862, + 79029415676722370 + ], + "c1": [ + 5692040832573735873, + 16884514497384809355, + 16717166481813659368, + 2742131088506155463 + ] + }, + "y": { + "c0": [ + 9604638503594647125, + 1289961608472612514, + 6217038149984805214, + 2521661352385209130 + ], + "c1": [ + 17168069778630926308, + 11309277837895768996, + 15154989611154567813, + 359271377050603491 + ] + }, + "infinity": false + } + ] +} \ No newline at end of file diff --git a/prover/data/historical_data/0.26.0/commitments.json b/prover/data/historical_data/0.26.0/commitments.json new file mode 100644 index 000000000000..086609a5822b --- /dev/null +++ b/prover/data/historical_data/0.26.0/commitments.json @@ -0,0 +1,6 @@ +{ + "leaf": "0xf9664f4324c1400fa5c3822d667f30e873f53f1b8033180cd15fe41c1e2355c6", + "node": "0xf520cd5b37e74e19fdb369c8d676a04dce8a19457497ac6686d2bb95d94109c8", + "scheduler": "0xe6ba9d6b042440c480fa1c7182be32387db6e90281e82f37398d3f98f63f098a", + "snark_wrapper": "0x14f97b81e54b35fe673d8708cc1a19e1ea5b5e348e12d31e39824ed4f42bbca2" +} \ No newline at end of file diff --git a/prover/data/historical_data/0.26.0/snark_verification_scheduler_key.json b/prover/data/historical_data/0.26.0/snark_verification_scheduler_key.json new file mode 100644 index 000000000000..acb7e3fe8969 --- /dev/null +++ b/prover/data/historical_data/0.26.0/snark_verification_scheduler_key.json @@ -0,0 +1,399 @@ +{ + "n": 16777215, + "num_inputs": 1, + "state_width": 4, + "num_witness_polys": 0, + "gate_setup_commitments": [ + { + "x": [ + 14543631136906534221, + 11532161447842416044, + 11114175029926010938, + 1228896787564295039 + ], + "y": [ + 13293602262342424489, + 8897930584356943159, + 13256028170406220369, + 3214939367598363288 + ], + "infinity": false + }, + { + "x": [ + 11488992528554025682, + 12016824828223971094, + 11942004360057333370, + 316831626296641307 + ], + "y": [ + 304673622018339856, + 7139037552557818730, + 12475560967982555143, + 1055588351918295250 + ], + "infinity": false + }, + { + "x": [ + 2274984630539920017, + 5398167177582250136, + 16440396753384808945, + 1037682586893548769 + ], + "y": [ + 10168660308952593373, + 16526369642614237721, + 569062739734175056, + 155645558476901406 + ], + "infinity": false + }, + { + "x": [ + 14005362797509427677, + 2662603874351919260, + 14261489165672308143, + 1470528288349794782 + ], + "y": [ + 11144229651170108862, + 11439490264313454962, + 114993091474760680, + 1037267173208738614 + ], + "infinity": false + }, + { + "x": [ + 10726125240955612787, + 1916320162213728495, + 1058608086768277905, + 1651114031905829493 + ], + "y": [ + 13237242732587628574, + 4774776044666137690, + 14401013098807103799, + 2514139699916115771 + ], + "infinity": false + }, + { + "x": [ + 14434760601334248377, + 5316938318287831815, + 6221098547630910324, + 980422841280734466 + ], + "y": [ + 9201886393750447942, + 3840149540273146267, + 18179910191622136829, + 1563809864380914603 + ], + "infinity": false + }, + { + "x": [ + 9586697317366528906, + 2325800863365957883, + 1243781259615311278, + 3048012003267036960 + ], + "y": [ + 612821620743617231, + 1510385666449513894, + 9368337288452385056, + 2949736812933507034 + ], + "infinity": false + }, + { + "x": [ + 11830690209042008764, + 11761396005838073769, + 18271188400274886574, + 2896734446482773484 + ], + "y": [ + 1890606551566554401, + 10220931290312275762, + 3256711195869515344, + 2466626485328709457 + ], + "infinity": false + } + ], + "gate_selectors_commitments": [ + { + "x": [ + 10865727529243127085, + 4083978853392244827, + 14303622309482785753, + 2263042021033673595 + ], + "y": [ + 3019601017411802529, + 880444282195426618, + 9998743525359587628, + 2891421025832200233 + ], + "infinity": false + }, + { + "x": [ + 5208608554346323426, + 8575970970223832576, + 2966209169082345602, + 239576408267301488 + ], + "y": [ + 17715084817752316452, + 2726293100894160682, + 17920596859559317135, + 3485576345363305439 + ], + "infinity": false + } + ], + "permutation_commitments": [ + { + "x": [ + 14761045450946573029, + 17157644513453531531, + 2555518804134782053, + 1415819224310783987 + ], + "y": [ + 17265629196749977462, + 4128711855633066822, + 8435602817910411328, + 1408116296902303196 + ], + "infinity": false + }, + { + "x": [ + 3307267823832528482, + 2406249680085831639, + 9091964031261402109, + 2846274000290842933 + ], + "y": [ + 17374905554931807856, + 6690578002079222163, + 11809376320193686210, + 2676076649992974574 + ], + "infinity": false + }, + { + "x": [ + 3159118708748226574, + 5508845413629697013, + 13350869305506486049, + 689297560178790472 + ], + "y": [ + 15696011303896469684, + 12551611148155235140, + 14438660833518031207, + 425021756161657108 + ], + "infinity": false + }, + { + "x": [ + 18349397811516917436, + 4473982696343317918, + 13070312540813307819, + 2109468484629113245 + ], + "y": [ + 13254534552549721008, + 17388411854346636521, + 17875890960520499518, + 1062184221180884481 + ], + "infinity": false + } + ], + "total_lookup_entries_length": 1787472, + "lookup_selector_commitment": { + "x": [ + 9324906502432882695, + 14977861238256290580, + 12538013124354067293, + 3408438202312564138 + ], + "y": [ + 14942105932194201701, + 12210090881357612547, + 14774705021036784261, + 2531694948512337448 + ], + "infinity": false + }, + "lookup_tables_commitments": [ + { + "x": [ + 10873859091125335643, + 3906092213625635374, + 17046157606087980048, + 3193402705223440293 + ], + "y": [ + 10158946293873382504, + 2171386304067884865, + 6918663094168980658, + 350601565475975409 + ], + "infinity": false + }, + { + "x": [ + 12822112641313049260, + 3646552465186399021, + 10324071010773924047, + 2209084192380614662 + ], + "y": [ + 11045141628975531869, + 12589678537679955590, + 3065046617868727674, + 2099447669854151830 + ], + "infinity": false + }, + { + "x": [ + 11395032673621937545, + 3000063650268118516, + 7857619430005721792, + 805706808484810738 + ], + "y": [ + 6817063666434679427, + 1646386051225388537, + 4677946977082722827, + 1369650305976868514 + ], + "infinity": false + }, + { + "x": [ + 2885179371868476351, + 159944842081142878, + 6092294387055034894, + 213843603626505240 + ], + "y": [ + 11868113133779277990, + 8509646480531194854, + 14088068011597639414, + 707070630614027545 + ], + "infinity": false + } + ], + "lookup_table_type_commitment": { + "x": [ + 1732877442096985191, + 7537030715658833452, + 14073502080301311448, + 2178792007727681099 + ], + "y": [ + 8513095304113652904, + 6581396660744182779, + 13939755637576387431, + 2477157044961106453 + ], + "infinity": false + }, + "non_residues": [ + [ + 5, + 0, + 0, + 0 + ], + [ + 7, + 0, + 0, + 0 + ], + [ + 10, + 0, + 0, + 0 + ] + ], + "g2_elements": [ + { + "x": { + "c0": [ + 5106727233969649389, + 7440829307424791261, + 4785637993704342649, + 1729627375292849782 + ], + "c1": [ + 10945020018377822914, + 17413811393473931026, + 8241798111626485029, + 1841571559660931130 + ] + }, + "y": { + "c0": [ + 5541340697920699818, + 16416156555105522555, + 5380518976772849807, + 1353435754470862315 + ], + "c1": [ + 6173549831154472795, + 13567992399387660019, + 17050234209342075797, + 650358724130500725 + ] + }, + "infinity": false + }, + { + "x": { + "c0": [ + 9089143573911733168, + 11482283522806384523, + 13585589533905622862, + 79029415676722370 + ], + "c1": [ + 5692040832573735873, + 16884514497384809355, + 16717166481813659368, + 2742131088506155463 + ] + }, + "y": { + "c0": [ + 9604638503594647125, + 1289961608472612514, + 6217038149984805214, + 2521661352385209130 + ], + "c1": [ + 17168069778630926308, + 11309277837895768996, + 15154989611154567813, + 359271377050603491 + ] + }, + "infinity": false + } + ] +} \ No newline at end of file diff --git a/prover/data/historical_data/README.md b/prover/data/historical_data/README.md index 22df8acd3384..8d368e249fa1 100644 --- a/prover/data/historical_data/README.md +++ b/prover/data/historical_data/README.md @@ -3,12 +3,17 @@ This directory contains historical verification keys and hashes. The name of the subdirectory should match the protocol version. -- 18 - boojum - 1.4.0 -- 19 - boojum fix -- 20 - fee model - 1.4.1 -- 21 - blobs - 1.4.2 -- 22 - fix - 1.4.2 -- 23 - 16 blobs + AA hashes + shared bridge - 1.5.0 -- 24 - 23 + fixes +| Version | Description | Circuit version | Other | +| ------- | ------------------------------------ | --------------- | ------------------ | +| 18 | boojum - 1.4.0 | 1.4.0 | | +| 19 | boojum fix | | | +| 20 | fee model - 1.4.1 | 1.4.1 | | +| 21 | blobs - 1.4.2 | 1.4.2 | | +| 22 | fix - 1.4.2 | | | +| 23 | 16 blobs + AA hashes + shared bridge | 1.5.0 | | +| 24.0 | 23 + fixes | | | +| 24.1 | fixes | | | +| 25.0 | protocol defence | | no circuit changes | +| 26.0 | gateway & bridges | | no circuit changes | And from version 24, we switched to semver (so 0.24.0, 0.24.1 etc). diff --git a/prover/data/keys/finalization_hints_compression_1.bin b/prover/data/keys/finalization_hints_compression_1.bin index 8f5cadc55c57..d71029042a99 100644 Binary files a/prover/data/keys/finalization_hints_compression_1.bin and b/prover/data/keys/finalization_hints_compression_1.bin differ diff --git a/prover/data/keys/finalization_hints_compression_2.bin b/prover/data/keys/finalization_hints_compression_2.bin index c6a4253d81e6..5dc0776779f4 100644 Binary files a/prover/data/keys/finalization_hints_compression_2.bin and b/prover/data/keys/finalization_hints_compression_2.bin differ diff --git a/prover/data/keys/finalization_hints_compression_3.bin b/prover/data/keys/finalization_hints_compression_3.bin index ef3f24e18c23..f8148a2cb2ee 100644 Binary files a/prover/data/keys/finalization_hints_compression_3.bin and b/prover/data/keys/finalization_hints_compression_3.bin differ diff --git a/prover/data/keys/finalization_hints_compression_4.bin b/prover/data/keys/finalization_hints_compression_4.bin index ca6c08bab1f1..d15a487c3572 100644 Binary files a/prover/data/keys/finalization_hints_compression_4.bin and b/prover/data/keys/finalization_hints_compression_4.bin differ diff --git a/prover/data/keys/finalization_hints_compression_wrapper_1.bin b/prover/data/keys/finalization_hints_compression_wrapper_1.bin new file mode 100644 index 000000000000..d71029042a99 --- /dev/null +++ b/prover/data/keys/finalization_hints_compression_wrapper_1.bin @@ -0,0 +1,35 @@ +{ + "row_finalization_hints": [ + [ + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + ], + "column_finalization_hints": [], + "nop_gates_to_add": 22419, + "final_trace_len": 65536, + "public_inputs": [ + [ + 0, + 43116 + ], + [ + 1, + 43116 + ], + [ + 2, + 43116 + ], + [ + 3, + 43116 + ] + ] +} \ No newline at end of file diff --git a/prover/data/keys/finalization_hints_compression_wrapper_5.bin b/prover/data/keys/finalization_hints_compression_wrapper_5.bin index cb61da940e2a..a9a54f2be7b2 100644 Binary files a/prover/data/keys/finalization_hints_compression_wrapper_5.bin and b/prover/data/keys/finalization_hints_compression_wrapper_5.bin differ diff --git a/prover/data/keys/verification_compression_1_key.json b/prover/data/keys/verification_compression_1_key.json index 3de9e823d17b..87ba550c1858 100644 --- a/prover/data/keys/verification_compression_1_key.json +++ b/prover/data/keys/verification_compression_1_key.json @@ -1,262 +1,260 @@ { - "CompressionMode1Circuit": { - "fixed_parameters": { - "parameters": { - "num_columns_under_copy_permutation": 52, - "num_witness_columns": 78, - "num_constant_columns": 4, - "max_allowed_constraint_degree": 8 - }, - "lookup_parameters": "NoLookup", - "domain_size": 65536, - "total_tables_len": 0, - "public_inputs_locations": [ - [ - 0, - 43116 - ], - [ - 1, - 43116 - ], - [ - 2, - 43116 - ], - [ - 3, - 43116 - ] + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 52, + "num_witness_columns": 78, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 65536, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 43116 ], - "extra_constant_polys_for_selectors": 4, - "table_ids_column_idxes": [], - "quotient_degree": 8, - "selectors_placement": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 1, - "num_constants": 0, - "degree": 7, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 4, - "num_constants": 4, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 2, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 6, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + [ + 1, + 43116 + ], + [ + 2, + 43116 + ], + [ + 3, + 43116 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 5, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 7, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 9, - "num_constants": 4, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 0, - "num_constants": 4, - "degree": 1, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 3, - "num_constants": 2, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 8, - "num_constants": 0, - "degree": 0, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "fri_lde_factor": 32, - "cap_size": 16 + } }, - "setup_merkle_tree_cap": [ - [ - 18429053439012828355, - 13569717100398864647, - 5674934326174107161, - 17602965228088658523 - ], - [ - 1853596005538808278, - 4863986522266180298, - 1446747858708973345, - 6556557904065432671 - ], - [ - 15389763462077761347, - 347990863686799186, - 9600431685918762723, - 18230110007683373373 - ], - [ - 4488979291903240149, - 15827713959121695389, - 5212372431509901484, - 15330056117710268303 - ], - [ - 2154621009093329369, - 2697922564969508975, - 8553713447457143603, - 11909287098676194610 - ], - [ - 17675899931204043754, - 1900641380227488316, - 13799770936458315711, - 16155696965522802314 - ], - [ - 4325071727231912895, - 15495124842543512517, - 7693387508183911518, - 2229191662604882855 - ], - [ - 12528623798638620709, - 7099783078856962509, - 1026199882135084179, - 7487829827063298337 - ], - [ - 17775767559834649815, - 11648203906640999220, - 18372230812591541111, - 2380029132644171876 - ], - [ - 17282415096853816692, - 7048528242178291549, - 1168458073834679094, - 4050365242852861872 - ], - [ - 12458945294827240519, - 9750085849866836452, - 10571283035096727478, - 296889776702427073 - ], - [ - 3087401981646414061, - 5145016559209358338, - 198041048326501493, - 16681321004258095323 - ], - [ - 15873896825395209700, - 17464513449028297769, - 6391802199611869536, - 24117562251396832 - ], - [ - 5930377685985813311, - 11344757707146885659, - 17036003029203547492, - 15372566160771512018 - ], - [ - 3165044285750289057, - 15764455157826377125, - 729334742516289605, - 8335221493745507200 - ], - [ - 318679242859206967, - 16131519447675179661, - 1921616860721123326, - 9785286945407043240 - ] + "fri_lde_factor": 32, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 18429053439012828355, + 13569717100398864647, + 5674934326174107161, + 17602965228088658523 + ], + [ + 1853596005538808278, + 4863986522266180298, + 1446747858708973345, + 6556557904065432671 + ], + [ + 15389763462077761347, + 347990863686799186, + 9600431685918762723, + 18230110007683373373 + ], + [ + 4488979291903240149, + 15827713959121695389, + 5212372431509901484, + 15330056117710268303 + ], + [ + 2154621009093329369, + 2697922564969508975, + 8553713447457143603, + 11909287098676194610 + ], + [ + 17675899931204043754, + 1900641380227488316, + 13799770936458315711, + 16155696965522802314 + ], + [ + 4325071727231912895, + 15495124842543512517, + 7693387508183911518, + 2229191662604882855 + ], + [ + 12528623798638620709, + 7099783078856962509, + 1026199882135084179, + 7487829827063298337 + ], + [ + 17775767559834649815, + 11648203906640999220, + 18372230812591541111, + 2380029132644171876 + ], + [ + 17282415096853816692, + 7048528242178291549, + 1168458073834679094, + 4050365242852861872 + ], + [ + 12458945294827240519, + 9750085849866836452, + 10571283035096727478, + 296889776702427073 + ], + [ + 3087401981646414061, + 5145016559209358338, + 198041048326501493, + 16681321004258095323 + ], + [ + 15873896825395209700, + 17464513449028297769, + 6391802199611869536, + 24117562251396832 + ], + [ + 5930377685985813311, + 11344757707146885659, + 17036003029203547492, + 15372566160771512018 + ], + [ + 3165044285750289057, + 15764455157826377125, + 729334742516289605, + 8335221493745507200 + ], + [ + 318679242859206967, + 16131519447675179661, + 1921616860721123326, + 9785286945407043240 ] - } + ] } \ No newline at end of file diff --git a/prover/data/keys/verification_compression_2_key.json b/prover/data/keys/verification_compression_2_key.json index 6110bba910d2..d0ee06b55fa2 100644 --- a/prover/data/keys/verification_compression_2_key.json +++ b/prover/data/keys/verification_compression_2_key.json @@ -1,275 +1,273 @@ { - "CompressionMode2Circuit": { - "fixed_parameters": { - "parameters": { - "num_columns_under_copy_permutation": 56, - "num_witness_columns": 74, - "num_constant_columns": 4, - "max_allowed_constraint_degree": 8 - }, - "lookup_parameters": "NoLookup", - "domain_size": 8192, - "total_tables_len": 0, - "public_inputs_locations": [ - [ - 0, - 6733 - ], - [ - 1, - 6733 - ], - [ - 2, - 6733 - ], - [ - 3, - 6733 - ] + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 56, + "num_witness_columns": 74, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 8192, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 6733 ], - "extra_constant_polys_for_selectors": 4, - "table_ids_column_idxes": [], - "quotient_degree": 8, - "selectors_placement": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 2, - "num_constants": 0, - "degree": 7, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 5, - "num_constants": 4, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 1, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 6, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + [ + 1, + 6733 + ], + [ + 2, + 6733 + ], + [ + 3, + 6733 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 3, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 7, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 10, - "num_constants": 4, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 8, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 9, - "num_constants": 0, - "degree": 0, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 10, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 4, - "num_constants": 2, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 0, - "num_constants": 4, - "degree": 1, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "fri_lde_factor": 512, - "cap_size": 16 + } }, - "setup_merkle_tree_cap": [ - [ - 547951636004245258, - 2067145936569319297, - 17315326678965070615, - 9012275275825325303 - ], - [ - 2486396189205338767, - 5385179748876990489, - 12789897155193748843, - 7497933664242847399 - ], - [ - 13702746436389342903, - 9589251880490084074, - 13207771356722054410, - 18277427829245158207 - ], - [ - 4132253692687914984, - 18227617432180132982, - 15881065677296839946, - 1403286368390823633 - ], - [ - 10537224762035068222, - 6013042199447780632, - 4527978597574086909, - 3232268373890188602 - ], - [ - 2586162944092407317, - 10215063509965051427, - 2471146708845362031, - 2843440288814318700 - ], - [ - 13819482850499157207, - 16859612470974380629, - 12731935288150853121, - 2902152945695153589 - ], - [ - 9392752661572461801, - 18377486933710861607, - 16200620130393023183, - 8365721844043961790 - ], - [ - 13954020715669265948, - 16716522360195023699, - 5205834515171426098, - 956788140632831896 - ], - [ - 3827733001679131898, - 17013298671136301019, - 3148453751188517867, - 16820158206874288178 - ], - [ - 2520856291381872645, - 4479900374678830382, - 13546063785562157656, - 3382667115615401371 - ], - [ - 15571586947246471933, - 17916455524698235528, - 4478607733734426679, - 12215920239082917056 - ], - [ - 12759564984587008435, - 5665565051416464627, - 4275508608287240845, - 7137116798231081511 - ], - [ - 5980650793630714101, - 9419587808931370936, - 7668041611691340219, - 1071524060976592787 - ], - [ - 8785315220105920748, - 14191148990050265889, - 8665763888918223523, - 10691214928896807830 - ], - [ - 16389667087475658615, - 7098223971082400278, - 3821718345101781981, - 17410025916491040451 - ] + "fri_lde_factor": 512, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 547951636004245258, + 2067145936569319297, + 17315326678965070615, + 9012275275825325303 + ], + [ + 2486396189205338767, + 5385179748876990489, + 12789897155193748843, + 7497933664242847399 + ], + [ + 13702746436389342903, + 9589251880490084074, + 13207771356722054410, + 18277427829245158207 + ], + [ + 4132253692687914984, + 18227617432180132982, + 15881065677296839946, + 1403286368390823633 + ], + [ + 10537224762035068222, + 6013042199447780632, + 4527978597574086909, + 3232268373890188602 + ], + [ + 2586162944092407317, + 10215063509965051427, + 2471146708845362031, + 2843440288814318700 + ], + [ + 13819482850499157207, + 16859612470974380629, + 12731935288150853121, + 2902152945695153589 + ], + [ + 9392752661572461801, + 18377486933710861607, + 16200620130393023183, + 8365721844043961790 + ], + [ + 13954020715669265948, + 16716522360195023699, + 5205834515171426098, + 956788140632831896 + ], + [ + 3827733001679131898, + 17013298671136301019, + 3148453751188517867, + 16820158206874288178 + ], + [ + 2520856291381872645, + 4479900374678830382, + 13546063785562157656, + 3382667115615401371 + ], + [ + 15571586947246471933, + 17916455524698235528, + 4478607733734426679, + 12215920239082917056 + ], + [ + 12759564984587008435, + 5665565051416464627, + 4275508608287240845, + 7137116798231081511 + ], + [ + 5980650793630714101, + 9419587808931370936, + 7668041611691340219, + 1071524060976592787 + ], + [ + 8785315220105920748, + 14191148990050265889, + 8665763888918223523, + 10691214928896807830 + ], + [ + 16389667087475658615, + 7098223971082400278, + 3821718345101781981, + 17410025916491040451 ] - } + ] } \ No newline at end of file diff --git a/prover/data/keys/verification_compression_3_key.json b/prover/data/keys/verification_compression_3_key.json index 63bcbca918d1..12ee585e2aa2 100644 --- a/prover/data/keys/verification_compression_3_key.json +++ b/prover/data/keys/verification_compression_3_key.json @@ -1,275 +1,273 @@ { - "CompressionMode3Circuit": { - "fixed_parameters": { - "parameters": { - "num_columns_under_copy_permutation": 68, - "num_witness_columns": 62, - "num_constant_columns": 4, - "max_allowed_constraint_degree": 8 - }, - "lookup_parameters": "NoLookup", - "domain_size": 4096, - "total_tables_len": 0, - "public_inputs_locations": [ - [ - 0, - 3921 - ], - [ - 1, - 3921 - ], - [ - 2, - 3921 - ], - [ - 3, - 3921 - ] + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 68, + "num_witness_columns": 62, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 4096, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 3921 ], - "extra_constant_polys_for_selectors": 4, - "table_ids_column_idxes": [], - "quotient_degree": 8, - "selectors_placement": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 2, - "num_constants": 0, - "degree": 7, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 5, - "num_constants": 4, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 1, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 6, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + [ + 1, + 3921 + ], + [ + 2, + 3921 + ], + [ + 3, + 3921 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 3, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 7, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 10, - "num_constants": 4, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 8, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 9, - "num_constants": 0, - "degree": 0, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 10, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 4, - "num_constants": 2, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 0, - "num_constants": 4, - "degree": 1, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "fri_lde_factor": 1024, - "cap_size": 16 + } }, - "setup_merkle_tree_cap": [ - [ - 10641025459109778062, - 11883023202620503830, - 1683460580494782039, - 519148484945527748 - ], - [ - 16854836347499347615, - 303914895048281273, - 8827365744032766288, - 7504886056916538809 - ], - [ - 18314198719448317357, - 10244100031050759980, - 9715483427672900470, - 13743747809877920521 - ], - [ - 1369713858293079339, - 2549296113044324317, - 10668787197724003505, - 13374818625902068059 - ], - [ - 11103822364554965998, - 1026596418533733662, - 11884006841460801711, - 16731940920918762822 - ], - [ - 8630324660886613970, - 15367922833873963141, - 538631244507362153, - 7257912375828853679 - ], - [ - 9919593341926293968, - 3835923795731948402, - 11747327108631657899, - 16458305757432722328 - ], - [ - 2324222966121258034, - 7413735041546781516, - 3485204485068670103, - 13438812829186206067 - ], - [ - 14474408113900929346, - 18061817840123336299, - 13649805566841328142, - 7129805169327250752 - ], - [ - 7300284926102090815, - 9725670656634972183, - 8151388754725946636, - 16128844202426193104 - ], - [ - 14707729241338825087, - 3836468945858242082, - 16768198593546824923, - 14062570092263697929 - ], - [ - 14327921344401839882, - 6479671009164937102, - 13089063982746955768, - 2683374136101896185 - ], - [ - 14787507835189907449, - 6738567890582174761, - 16728637974735308667, - 537766695323716501 - ], - [ - 8795483109816567655, - 14842674875555441461, - 11332449659964817297, - 4865859390541196365 - ], - [ - 11192585970910716125, - 3048970808099494060, - 7684470944992674010, - 9304044469675055850 - ], - [ - 5655924464102745207, - 8506077190272738679, - 8512156535337592685, - 15415747564657306809 - ] + "fri_lde_factor": 1024, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 10641025459109778062, + 11883023202620503830, + 1683460580494782039, + 519148484945527748 + ], + [ + 16854836347499347615, + 303914895048281273, + 8827365744032766288, + 7504886056916538809 + ], + [ + 18314198719448317357, + 10244100031050759980, + 9715483427672900470, + 13743747809877920521 + ], + [ + 1369713858293079339, + 2549296113044324317, + 10668787197724003505, + 13374818625902068059 + ], + [ + 11103822364554965998, + 1026596418533733662, + 11884006841460801711, + 16731940920918762822 + ], + [ + 8630324660886613970, + 15367922833873963141, + 538631244507362153, + 7257912375828853679 + ], + [ + 9919593341926293968, + 3835923795731948402, + 11747327108631657899, + 16458305757432722328 + ], + [ + 2324222966121258034, + 7413735041546781516, + 3485204485068670103, + 13438812829186206067 + ], + [ + 14474408113900929346, + 18061817840123336299, + 13649805566841328142, + 7129805169327250752 + ], + [ + 7300284926102090815, + 9725670656634972183, + 8151388754725946636, + 16128844202426193104 + ], + [ + 14707729241338825087, + 3836468945858242082, + 16768198593546824923, + 14062570092263697929 + ], + [ + 14327921344401839882, + 6479671009164937102, + 13089063982746955768, + 2683374136101896185 + ], + [ + 14787507835189907449, + 6738567890582174761, + 16728637974735308667, + 537766695323716501 + ], + [ + 8795483109816567655, + 14842674875555441461, + 11332449659964817297, + 4865859390541196365 + ], + [ + 11192585970910716125, + 3048970808099494060, + 7684470944992674010, + 9304044469675055850 + ], + [ + 5655924464102745207, + 8506077190272738679, + 8512156535337592685, + 15415747564657306809 ] - } + ] } \ No newline at end of file diff --git a/prover/data/keys/verification_compression_4_key.json b/prover/data/keys/verification_compression_4_key.json index 5bd28e4d6d6b..821fb25d4048 100644 --- a/prover/data/keys/verification_compression_4_key.json +++ b/prover/data/keys/verification_compression_4_key.json @@ -1,1741 +1,1739 @@ { - "CompressionMode4Circuit": { - "fixed_parameters": { - "parameters": { - "num_columns_under_copy_permutation": 48, - "num_witness_columns": 0, - "num_constant_columns": 4, - "max_allowed_constraint_degree": 8 - }, - "lookup_parameters": "NoLookup", - "domain_size": 32768, - "total_tables_len": 0, - "public_inputs_locations": [ - [ - 0, - 31025 - ], - [ - 1, - 31025 - ], - [ - 2, - 31025 - ], - [ - 3, - 31025 - ] + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 48, + "num_witness_columns": 0, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 32768, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 31025 ], - "extra_constant_polys_for_selectors": 4, - "table_ids_column_idxes": [], - "quotient_degree": 8, - "selectors_placement": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 4, - "num_constants": 1, - "degree": 7, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 7, - "num_constants": 4, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 1, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 8, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + [ + 1, + 31025 + ], + [ + 2, + 31025 + ], + [ + 3, + 31025 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 1, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 5, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 9, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 12, - "num_constants": 4, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 10, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 3, - "num_constants": 0, - "degree": 1, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 11, - "num_constants": 0, - "degree": 0, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 12, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 10, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 0, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 11, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false } } } } - }, - "right": { - "GateOnly": { - "gate_idx": 2, - "num_constants": 0, - "degree": 1, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 1, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 6, - "num_constants": 2, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 0, - "num_constants": 4, - "degree": 1, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "fri_lde_factor": 1024, - "cap_size": 256 + } }, - "setup_merkle_tree_cap": [ - [ - 4079970138244939135, - 8104423815789893989, - 13632023733358255593, - 13346032064987220184 - ], - [ - 12809474467971181399, - 17625072709782170540, - 6594064732490183681, - 8714625183861721175 - ], - [ - 7171332554251640845, - 18284102552959382973, - 3637671217742590741, - 16765711635591410580 - ], - [ - 763060458426938791, - 16159161330183244037, - 2533596966746622429, - 13441156130846388257 - ], - [ - 5525639466278377590, - 11073269405581050439, - 4833809564449931762, - 9314656237570540457 - ], - [ - 1137979745697828455, - 14966651582384421379, - 13384164937770371175, - 14074716572336098280 - ], - [ - 11906323633157650458, - 1175046947414337453, - 4283188400738641426, - 13792950671402095073 - ], - [ - 9310952691940114113, - 4820182619662404377, - 9479969369442954044, - 8512369778696933060 - ], - [ - 16946138649176650488, - 9475913097060757863, - 6608972026504748865, - 7215353463715689998 - ], - [ - 349222139041408316, - 1507489261015035841, - 7596560681014222842, - 8808235055298411214 - ], - [ - 8007370340350072341, - 2549612240734498963, - 105233771877650291, - 8758305155554767568 - ], - [ - 17190433766023179459, - 1755290160765045579, - 5619893747453895498, - 9139477571875211116 - ], - [ - 15755591792726495281, - 17501027650687476798, - 5579351800673089158, - 5931628352091930640 - ], - [ - 7269556889579729096, - 8636006399519326592, - 15556402257631967994, - 12423945489648480054 - ], - [ - 6411602498376025591, - 16377643789139599240, - 1264958035077382258, - 16706608130239118866 - ], - [ - 14246313207191082462, - 2201136836754342130, - 12301078636732201867, - 10991169525653220176 - ], - [ - 2101214821629968022, - 11996351959015322539, - 15461759537099893272, - 5820786797852667153 - ], - [ - 10546547765646585412, - 16670337245061195679, - 14026017154393171841, - 15865302123450709636 - ], - [ - 14546229884213013754, - 1736742091912698149, - 9563343697509131991, - 15957923614096898715 - ], - [ - 10053685874691243725, - 4837706724113512400, - 2806343138575002644, - 1217140278849814125 - ], - [ - 1445801437405723985, - 16370378782744105412, - 14937074551650631907, - 9349528097788576916 - ], - [ - 313624596753562026, - 2737902703720676400, - 1491628534561577719, - 4958865646973460786 - ], - [ - 4749220647213961766, - 1523283588343260013, - 14435216093380418825, - 12058673416937256217 - ], - [ - 12221430523773573392, - 2119312783391782040, - 113666136908336034, - 5557001496562966971 - ], - [ - 8943540790257615175, - 15963411684352909178, - 12833466372967679781, - 16755820399299554647 - ], - [ - 10568513175105063273, - 8152439411055527457, - 13191469024927433668, - 16583335250317103083 - ], - [ - 8728976170665901948, - 12047344511237318236, - 2665537844838432218, - 17220904479682973198 - ], - [ - 9924606303320583729, - 15168541434821629608, - 15267127988736394576, - 4612730729137963542 - ], - [ - 15187295020445613202, - 10979580190616738578, - 2487576517666265788, - 7799526392944971411 - ], - [ - 14001553124798608592, - 983427750240831173, - 10498633617369923042, - 15506856636873354247 - ], - [ - 9695584132680310661, - 15058940491468263542, - 16902767176197422459, - 4307070711535476522 - ], - [ - 16170129192711277380, - 15594325905653564554, - 8589261531750893019, - 16380506012444184509 - ], - [ - 1298482137029698068, - 7046350962355653091, - 4851290198964994943, - 9583994567704854822 - ], - [ - 12002196043506075596, - 6568364019768992619, - 2982180816490272604, - 11005221893883916442 - ], - [ - 11195444762924129211, - 4080035169749061493, - 12552903944803877103, - 1737834024116304977 - ], - [ - 14989371064091658414, - 7021573041416327989, - 10313274026717983047, - 12022812057768375145 - ], - [ - 4605818886224729183, - 1445887803225464457, - 10940822604464014966, - 9884898953608657154 - ], - [ - 16595525430044003662, - 4052207436631314262, - 10293047811043558578, - 12338411972889057265 - ], - [ - 17022547446139753073, - 10651710177937554340, - 6940830771318907626, - 6641453047926556761 - ], - [ - 10509711725088536487, - 4962100381463002257, - 770256729671337313, - 5857473086438310769 - ], - [ - 13267845343537121240, - 12321261427265206453, - 7120567552214639265, - 17302478469072029437 - ], - [ - 15157833123384882226, - 8158551777234184706, - 12348570826200339644, - 14734791159756873167 - ], - [ - 3385809684799950973, - 12900259269431347094, - 17672545490781962423, - 8013657472810936941 - ], - [ - 9546288143416776531, - 8356139039634733121, - 17477514712681213981, - 9515108802170635886 - ], - [ - 15455406291521834876, - 18083571768045422071, - 2009769659787731673, - 7263333966403015872 - ], - [ - 61130843037975416, - 18121830552682131571, - 9667884638217866764, - 6932529860678316702 - ], - [ - 15509823136620654552, - 6676934950708893059, - 13351533805402596549, - 14340984679679191575 - ], - [ - 15880919573481609124, - 14836853565796210968, - 15058034487233879726, - 11000215022533975317 - ], - [ - 10611445668418674805, - 9013654201900818768, - 1617123938865368568, - 16484766808972651318 - ], - [ - 13652743593752436493, - 13843264938563223779, - 10417182020840583510, - 16106479734523413326 - ], - [ - 17003899699844258217, - 17283344455088140068, - 17379245612757089745, - 1779134255761065541 - ], - [ - 11263035503709897880, - 1042839549428969974, - 6638626002246118718, - 1733549590874866310 - ], - [ - 13054247239013491523, - 14047141927303128296, - 2417752406294216107, - 5255181314162279551 - ], - [ - 1784021430104795099, - 3912913366054617723, - 8208877227749479136, - 4259205675774136108 - ], - [ - 801501735568309733, - 3220301656144181340, - 6144806934797449899, - 10479314068206076631 - ], - [ - 864619228795552444, - 2705960387071331097, - 15702747436396598972, - 14131926486457006694 - ], - [ - 15349058561965444062, - 16738574548455051915, - 4609208407223910426, - 11352062762791244662 - ], - [ - 16513285945090237658, - 6443875617703638442, - 17271016792575259072, - 426511686464611712 - ], - [ - 13863640462921288570, - 3362196992389213358, - 3576502768827883720, - 49219399301262346 - ], - [ - 14852014958673205840, - 11855705779815876870, - 8141476064801289266, - 15234506534160954104 - ], - [ - 6292328028167907211, - 6280576736728723621, - 1814915348986377963, - 3167789754322444841 - ], - [ - 6093870088272451581, - 12912333461662707605, - 16038365026642624017, - 10037265733136426182 - ], - [ - 5658473063427008398, - 18194712009700816671, - 3316188885192160812, - 15032222957557455487 - ], - [ - 10746739009272326386, - 4381896503060636995, - 13390900032103397758, - 11290296227744685851 - ], - [ - 7946268274905655961, - 12464655577446728520, - 3476152367809517039, - 3103729420470642525 - ], - [ - 15652670185218353632, - 17922284652588341925, - 3502474425690015164, - 3577240886292713575 - ], - [ - 13130871911189865405, - 2598654314674217849, - 6130707868677033708, - 11318789126458218054 - ], - [ - 14442525432094720658, - 10861520212227307580, - 10308956417568414174, - 101391938116250123 - ], - [ - 8015353735581004985, - 11791356411393233202, - 15134704188872104026, - 2916434958525680154 - ], - [ - 17776268955107890735, - 3978578384988358930, - 7512482176825678493, - 4207030036138354730 - ], - [ - 4778990000266723258, - 12646326430153649418, - 15602744563429649630, - 13225673449752707138 - ], - [ - 9874615904187846642, - 785813436574501824, - 7422887093860615814, - 12575067740028803899 - ], - [ - 2168314129068013776, - 5876170257821873353, - 6574425448964925595, - 13006818379253162445 - ], - [ - 18203396842093379784, - 1637929000957737331, - 16472903772026963266, - 10222221849709050007 - ], - [ - 8175241234035594021, - 11131701218615583700, - 2590544239124773213, - 13103205380700956240 - ], - [ - 10265760611171832222, - 10772001381712818941, - 9769892419500727073, - 3757944212165946207 - ], - [ - 12890674101364520820, - 17436315026775313277, - 17685632275460283213, - 11597862884205200021 - ], - [ - 6541476428026208530, - 1572664979326233234, - 7220008363221767753, - 5030515443926464143 - ], - [ - 1736392533925503753, - 4028348047388923757, - 1322644146499193870, - 7899110541856172042 - ], - [ - 824249951832333568, - 3650442342240934725, - 9551872020421810878, - 4459093260544332906 - ], - [ - 4897538583957298940, - 9763535759998548001, - 17962120881583547780, - 16423532894596203353 - ], - [ - 15621981029420175013, - 12716027808121583594, - 5698997410684688521, - 14893034348453337964 - ], - [ - 57123003983559085, - 1764189019842202487, - 12021079431755992353, - 4611397927843211028 - ], - [ - 11271204071286517021, - 11016763947620063917, - 10240257375147160558, - 6936015967868091242 - ], - [ - 13263159746058683924, - 2115544844352440396, - 17037308825725243672, - 15392971905394245550 - ], - [ - 3040132672294734369, - 8799577028392802142, - 4698252977355096983, - 12029143421110018733 - ], - [ - 3367138533962530706, - 11052858577054708144, - 13777717310915519372, - 1118835749836496249 - ], - [ - 18247935773305597594, - 4791613470261596504, - 2831278673598556804, - 13054754323096013606 - ], - [ - 16660028838922677973, - 9396606308613201784, - 10417460426584440111, - 8380249813777095858 - ], - [ - 8666375557464313815, - 6304275044317841466, - 17005733772133350822, - 14343984316653970581 - ], - [ - 6123226050306352446, - 17155936354664339685, - 8617663439980301335, - 15168460408431057703 - ], - [ - 4711490317757564870, - 4007952793500570494, - 1619724888362180342, - 135640370275358583 - ], - [ - 3568489405188009952, - 10063008786740635782, - 3645030669998184283, - 11251876386972219611 - ], - [ - 8493411482257270591, - 2420069605766207080, - 4319637578909518850, - 7366398383772225801 - ], - [ - 10514279907222008963, - 4576784878418470993, - 13703409256143697610, - 12595458216589602418 - ], - [ - 6518196967791403281, - 6267315352755318878, - 17017845178414282191, - 6219869337455185408 - ], - [ - 9419176152740350408, - 7255025946876060056, - 13692775553690785222, - 6482964045212267647 - ], - [ - 10371771524251272238, - 7264554963155886115, - 11851596230763322123, - 9644034659422561803 - ], - [ - 16478128758974022864, - 10586973455001136017, - 10940854718906381238, - 4322569144361190672 - ], - [ - 1408324526595066767, - 8225966379387133915, - 575234437450946120, - 4532159296152332514 - ], - [ - 14713730919085929141, - 8299030584912591200, - 12653081274697230155, - 7281510145820913452 - ], - [ - 13065256168386635886, - 11725981090441231815, - 9241488846717901227, - 2660860847185625194 - ], - [ - 17344786539017984359, - 16667262327893622443, - 2245517842543022928, - 5289295469095289187 - ], - [ - 7712996453163241402, - 13291387059438293554, - 15475873660461985862, - 421113001330390910 - ], - [ - 6600556276994686684, - 15236925279661890975, - 9085425445873596043, - 13489979627098239874 - ], - [ - 16522817509787049424, - 7880119001244729499, - 2065132977854154043, - 13961595284131100852 - ], - [ - 10136466656472241068, - 7462847284592418995, - 5211060891495522982, - 3429812446680794228 - ], - [ - 1290650595638649346, - 13577818566931833714, - 2388552128026682549, - 13062451014076475307 - ], - [ - 6070278064232182539, - 12399409837026713208, - 7006572737093555522, - 15229533042676039053 - ], - [ - 4546934482854074283, - 12178466512696871783, - 1691876649621188863, - 11473100481876466355 - ], - [ - 1236556729692669368, - 5549499687074217624, - 5958432331744161923, - 17960851426383425726 - ], - [ - 11313384441935481196, - 506230122531558484, - 17480105233549292653, - 3497216050489019068 - ], - [ - 14180330000703954943, - 17537654316605413864, - 13893109338811179145, - 12773435230801104558 - ], - [ - 1789329554161917105, - 3821166735342421302, - 492899993274707886, - 12499398353307226422 - ], - [ - 3089012429777109607, - 10341877957962585240, - 7745611914889843192, - 7156440096296115871 - ], - [ - 14047653524331542619, - 14986552290847971271, - 8344707263938736217, - 5768162811052933747 - ], - [ - 3282503115484594392, - 3455102204735354908, - 6152707383721113591, - 17881334209336571790 - ], - [ - 6895592993382091339, - 14944664838702526606, - 14158277091240311047, - 13527182248087302901 - ], - [ - 3709694612749923839, - 2612160447494745836, - 1406956200130224054, - 1366284088614500522 - ], - [ - 9948565747047514924, - 7052268914527763961, - 18019747825808196928, - 14284818641981927036 - ], - [ - 3586214080877747437, - 18259935751422321449, - 7615481956713457290, - 14815795422370035012 - ], - [ - 127402153735286355, - 14056365981282611643, - 13874770993027970720, - 619630456240824192 - ], - [ - 14160230678035047748, - 5889480608083619036, - 7255863117098942211, - 15199656156616971091 - ], - [ - 3095946492180700178, - 4006392168790405864, - 6879209997262175243, - 299198988833119182 - ], - [ - 7324876720724904977, - 16163169761447383767, - 12506750534396872240, - 2471214392724636123 - ], - [ - 9097827375986012190, - 14565705700237004602, - 14313871429102448506, - 11871591868576605558 - ], - [ - 9799079875206163527, - 16651435323107739422, - 12479220145998529239, - 3293893419326195678 - ], - [ - 10308258292354323463, - 12348814193023657478, - 7617037745166680507, - 4395321161975898727 - ], - [ - 5350571522462508856, - 13168312859432101164, - 16051585591307343397, - 14229124174436500603 - ], - [ - 7166265506509230502, - 7161154874163920078, - 8397077088165043439, - 11599821267858973994 - ], - [ - 7480649953471058826, - 10095090134750662786, - 10564643199160392009, - 13520621355659318250 - ], - [ - 10857779123272725120, - 15686674254635154618, - 8867730228951457290, - 10801878621148582310 - ], - [ - 15060256657026761959, - 9661131710054923901, - 672914961534049680, - 12834176932586128630 - ], - [ - 949448556211506716, - 15381404281513795275, - 11155631745566842701, - 2704703395424058389 - ], - [ - 9515248836992226419, - 8107063249314601218, - 7169007343668853680, - 4398533039543530267 - ], - [ - 5048521287079394266, - 469091126174822039, - 15224036421670482877, - 2109812614761568090 - ], - [ - 16374381239073062350, - 1415659237932604676, - 15755278916993952324, - 4477381067900828660 - ], - [ - 5908643369108814128, - 16993840892601214320, - 9745154490046936812, - 12675544964328790510 - ], - [ - 13069705042519055121, - 114347527485448732, - 13607966080279761362, - 3198027414138631154 - ], - [ - 2126201229935790021, - 11762486874095747924, - 4405447136645256490, - 4546150485765128281 - ], - [ - 11517522298498019347, - 9683562397139382420, - 17997189851623366056, - 15075626419278367114 - ], - [ - 17300749044902256514, - 13180322067670835054, - 13510754977375972746, - 16789287824862069583 - ], - [ - 12482184120647536152, - 6673581288163589602, - 12763923036507066435, - 14094147320392535720 - ], - [ - 14259634259170511729, - 4875730172347810212, - 84468584086030163, - 8303744294867418687 - ], - [ - 12134644548742181831, - 8520649738990136053, - 16059641390155564470, - 5416979754786543764 - ], - [ - 2092318536537973522, - 11767101658840205425, - 6426865564773940591, - 14647807617379392454 - ], - [ - 450267335414320409, - 9743488482513949727, - 60939637019009091, - 17766639401038188429 - ], - [ - 10940698167282175513, - 14751185897733548414, - 12951179730146965260, - 10875205992060835228 - ], - [ - 13364210655207872649, - 6433202412249539021, - 9336639704508334838, - 13505754981533474450 - ], - [ - 13696994814871272283, - 4490009507613100808, - 13804331039068475494, - 5468505803402562249 - ], - [ - 4777271447313491592, - 9940020440702119485, - 1101181637482946058, - 644606693604161858 - ], - [ - 15097959041405784257, - 12307130809829041484, - 17258499521253983865, - 10749514694060779271 - ], - [ - 10190208760039486310, - 4226050742652743727, - 8941293745652956008, - 16590522505585423775 - ], - [ - 345192297192706835, - 446809322130030426, - 14301758245246751976, - 9719056934946360728 - ], - [ - 12881116110058824616, - 9527685388634025534, - 11091584611747550280, - 17824266919172201804 - ], - [ - 1574239507079237453, - 8582461342969153012, - 12264251495254783586, - 17637680562426650364 - ], - [ - 10192143269632239849, - 13007991288866360616, - 15140175217087410009, - 12752906480866993968 - ], - [ - 1870988781431107523, - 12976682012942521853, - 16429062848935476734, - 5798003006437035985 - ], - [ - 14584766751103981854, - 17047930049374537599, - 16615811923791215213, - 4382675641211926136 - ], - [ - 2714557854446349417, - 7104188094330759435, - 4252584297915226480, - 8214575447584991866 - ], - [ - 11055975993893155083, - 4263965260378501220, - 14890629048371839452, - 12114106467257211085 - ], - [ - 1696215674801501046, - 2266423673248165355, - 17663731467117251495, - 3131727223950690444 - ], - [ - 9538270027605424981, - 14695627410990929758, - 1100103051852107643, - 7780696685697285282 - ], - [ - 3640909033400638252, - 4685184407249885115, - 1159593584695683466, - 5810155451150284456 - ], - [ - 2142365296746734893, - 15072293834204351367, - 10906328353503930623, - 567086761313849045 - ], - [ - 16792244974449676806, - 5281042885555694958, - 803668749758477336, - 9632569928427671141 - ], - [ - 11458024915503659884, - 12163640565717382175, - 5426693528062973190, - 5318451835514658298 - ], - [ - 17468129298890753615, - 16365877952312079431, - 4255216049796249864, - 17519162521801620751 - ], - [ - 16881958987441626136, - 5348165195536725074, - 1110205049250373278, - 3270960662287149636 - ], - [ - 1226689297335858879, - 5569006707448968175, - 12862213669554513549, - 13476251685033412618 - ], - [ - 17469709307599228055, - 10239286546577328519, - 11089348310818650527, - 16456908862000481769 - ], - [ - 1488822551903623063, - 1027724056630207939, - 17697306299429716060, - 16855149560650760331 - ], - [ - 6973362373999440967, - 10660889882557485296, - 10425405668156759777, - 6301066711999204638 - ], - [ - 414734469595850357, - 14255487988571755338, - 8593074929345797359, - 16605827151888774599 - ], - [ - 16875797800314241514, - 12421815564591930411, - 2652019482537730851, - 6038511721575984408 - ], - [ - 5083130506118840282, - 10236076700696608757, - 89798661707215807, - 11047945556430945234 - ], - [ - 9052849932438286930, - 766869919370273028, - 9513938692410545262, - 9325822678740812785 - ], - [ - 12214954222172122496, - 2137993706327729295, - 9068121284446752470, - 16719368474204358065 - ], - [ - 12846496216910539260, - 14961944612175511231, - 4871177192578157967, - 871092876547424272 - ], - [ - 8432570778385641968, - 16742266319428376459, - 5202631662503988626, - 9179077767480984950 - ], - [ - 6907086971366422845, - 3630230185711868320, - 6363326632303072661, - 2155376917773117715 - ], - [ - 7260111458604834720, - 15869987976273960274, - 5471864801301693834, - 6186332987204233992 - ], - [ - 7579472070725254127, - 4175627325036864033, - 2726864388901619006, - 17182366690618521544 - ], - [ - 10366850615209571638, - 594983328964439422, - 5708701194817491298, - 8320252948121397632 - ], - [ - 7681701787398279771, - 8922827186766353002, - 16390646056989747875, - 16861016347708202354 - ], - [ - 18349539097929417681, - 11011444774390028397, - 14929165998832565332, - 4785028369071377058 - ], - [ - 12474665121325276393, - 6203136048752329670, - 8857782650797383532, - 1205842604249274162 - ], - [ - 4986065786927816995, - 16774907198741044886, - 3781179129421387661, - 10415439284245950953 - ], - [ - 11574881136629381449, - 12379735189792408408, - 16543138864606381298, - 2352837174543239308 - ], - [ - 2755808935111250351, - 11413691641496289631, - 7433067894962399074, - 9263092778396333619 - ], - [ - 510815690565069916, - 1326078112306964442, - 2280931398968953373, - 16372347667232436246 - ], - [ - 13049250986319352420, - 1312888884206484061, - 5191125907416704942, - 12910692959434040696 - ], - [ - 12641131533859353693, - 806990755667531292, - 8339582499246533062, - 15459494525405539126 - ], - [ - 5334506198163160487, - 12788298331318017466, - 3878039519170214619, - 14733573925349283487 - ], - [ - 5190557862976962645, - 13714749928322729293, - 10374841881342744627, - 15288181470367912639 - ], - [ - 16231478233162755783, - 12802076246758748329, - 14761367109514758527, - 14411193599867587859 - ], - [ - 8198731374774297764, - 3230920736551397516, - 11406632512199098782, - 10984385724696684374 - ], - [ - 2230082119129443391, - 15626857176238648658, - 10525636546408036753, - 713830293126230928 - ], - [ - 4947353515945045110, - 14890750024678328507, - 11992121003625623155, - 9247439145474008589 - ], - [ - 2476255618728017726, - 12423839440278091466, - 11131574346213868564, - 15878857548422208415 - ], - [ - 14063080495591128251, - 17832973426635180302, - 16234044432643152520, - 3790040177800561340 - ], - [ - 17654367747593125286, - 14771556851404254590, - 7054247606189603403, - 16389491650139306501 - ], - [ - 16945878684828151504, - 3218677612764542854, - 4129066622553533042, - 12411143505986390453 - ], - [ - 18139421373310678346, - 12565918292252415379, - 15834446535016534449, - 6148063108469358612 - ], - [ - 12292679265601130740, - 13386299384345137465, - 13364501573803460934, - 8733289102497600737 - ], - [ - 6160628888236701076, - 812243480588759160, - 13247424403141713486, - 10099500208290322254 - ], - [ - 10969580462260030094, - 16960852675866882693, - 14194600920049272873, - 2806447904271636378 - ], - [ - 5308612537476412691, - 2017232117327961782, - 4894043882170046108, - 7279530397891640384 - ], - [ - 4144733560007592583, - 5771344498053405563, - 15232642512723560772, - 17432794023851843115 - ], - [ - 13083133801966421336, - 6640909047775641455, - 7780326336877273740, - 3087015496142074629 - ], - [ - 4093431377560277258, - 11212918479165511440, - 8471957796338043904, - 10134266515436065987 - ], - [ - 7717602192687906239, - 16498238127262085325, - 2796866393834457756, - 6080730252731365434 - ], - [ - 15198975112515001105, - 3427384774999580491, - 9100144446909554927, - 12939101842468805683 - ], - [ - 3513270711153070627, - 6760090775854266850, - 2266114679123970134, - 2453164217927145379 - ], - [ - 8454909244339253322, - 3937159550392777548, - 17092850706817714179, - 14355781411083550660 - ], - [ - 14878805576521609961, - 14710363931287834639, - 3026158727470434848, - 664513313042659381 - ], - [ - 8491751794767535837, - 13990906406579930747, - 10128524312616192734, - 11329057191619161908 - ], - [ - 14453858867510385195, - 7990714203132759977, - 5706371533563158927, - 4128865490009717707 - ], - [ - 7793399965923611298, - 13429890700846305668, - 6463577189314693043, - 1403793223780405881 - ], - [ - 14506683092001193039, - 2676502583153744002, - 432387115071868059, - 5324230977146090619 - ], - [ - 5163412501615965388, - 13723489526376938207, - 13122017355634831416, - 9867447233188068220 - ], - [ - 2169005641163984550, - 9186165665928554404, - 17910278673295197365, - 11381918494994166306 - ], - [ - 5758488670302072688, - 18181832326798847807, - 10253561012448568621, - 6796662601196927726 - ], - [ - 15384372095875884299, - 15758325895562962606, - 979979951038690002, - 4884709252008623452 - ], - [ - 9658033725016409161, - 11061216333798295999, - 10656853269529126466, - 10494481123210514991 - ], - [ - 10565302142069456280, - 4482395191206056917, - 1026499487185603956, - 7313927946426328835 - ], - [ - 914075172237814299, - 4712333083011398137, - 5903513285138462152, - 27234332817070790 - ], - [ - 6165097805071238615, - 12405114942064306895, - 644764352603959519, - 9890780672007958877 - ], - [ - 15139300154181340570, - 3763515407393500498, - 747278468332165545, - 12401993133389174873 - ], - [ - 1560524376846745097, - 4692895970840561536, - 8733218268882211058, - 11050746819680980390 - ], - [ - 2481724169828996194, - 13708290945708520871, - 4344699263192501279, - 7140288180697285542 - ], - [ - 296768972336373070, - 10813546555235346490, - 16170115378690748299, - 12802703395795280191 - ], - [ - 14251656741089442088, - 4214370918062569580, - 10032045984805229135, - 10373930023291015419 - ], - [ - 17093829866009459220, - 12859940170163163826, - 18210851741109329458, - 16336121553624015019 - ], - [ - 4407838941860440582, - 11854162025145257857, - 12199975997855699065, - 2502264419023857875 - ], - [ - 12466276041107521420, - 5321886014476179588, - 7215900333286173827, - 6244069735947509039 - ], - [ - 5660993473650802623, - 11420246285415070761, - 4658057095848491886, - 6674509485613885322 - ], - [ - 16443753989364975722, - 553371339109155814, - 6176240530340905521, - 5112633271096324804 - ], - [ - 17344015413911877127, - 17921285748955845167, - 472207513366524064, - 9508903352311585055 - ], - [ - 2373580342727259876, - 17626197481532596235, - 5443748763702275935, - 16239948710647217063 - ], - [ - 1893590215294085348, - 16922448579707654020, - 3562803535149926022, - 5008057946422210179 - ], - [ - 9528486283906265098, - 16540897732900210948, - 7987610981843235045, - 8503796247003141361 - ], - [ - 7151582572260738324, - 8798367050545135378, - 17208414855521381994, - 16950417755338618580 - ], - [ - 16098392335079248174, - 15218667139563807688, - 3579977320329860139, - 5640122365751888962 - ], - [ - 9584075531015381817, - 16275032664923657166, - 13987470479712899701, - 2201274726914907785 - ], - [ - 9927398107804295577, - 5687396867124688978, - 10639332412514046012, - 10390174472889436172 - ], - [ - 7906944927470502930, - 9629467849018808831, - 16716405557811073978, - 2687565502976952246 - ], - [ - 2357326643063601119, - 12372080030488676843, - 17862973568880540528, - 9758076484635237383 - ], - [ - 6955909340644692347, - 9788637714503672561, - 10015565612607022102, - 5622624961359105679 - ], - [ - 8476474886341847071, - 14658488683343597259, - 14961921379651609802, - 14123545985510427091 - ], - [ - 1388357604146037902, - 15713286211316016536, - 5612470285625982657, - 6487364037172184435 - ], - [ - 15189267229737199628, - 6502744762576006736, - 13803864300857374808, - 5415597147102054081 - ], - [ - 11784930967835797340, - 11401415610557072973, - 1534900691166631710, - 4724373879472771719 - ], - [ - 10801273164646452905, - 11959510535773071656, - 13440563277297614072, - 11732355214966685480 - ], - [ - 709242285317259075, - 14093566268118334778, - 17068650979174969466, - 14497803119243527377 - ], - [ - 1887862044793269490, - 8537802901513975848, - 1791222441789963991, - 9563652556460700888 - ] + "fri_lde_factor": 1024, + "cap_size": 256 + }, + "setup_merkle_tree_cap": [ + [ + 4079970138244939135, + 8104423815789893989, + 13632023733358255593, + 13346032064987220184 + ], + [ + 12809474467971181399, + 17625072709782170540, + 6594064732490183681, + 8714625183861721175 + ], + [ + 7171332554251640845, + 18284102552959382973, + 3637671217742590741, + 16765711635591410580 + ], + [ + 763060458426938791, + 16159161330183244037, + 2533596966746622429, + 13441156130846388257 + ], + [ + 5525639466278377590, + 11073269405581050439, + 4833809564449931762, + 9314656237570540457 + ], + [ + 1137979745697828455, + 14966651582384421379, + 13384164937770371175, + 14074716572336098280 + ], + [ + 11906323633157650458, + 1175046947414337453, + 4283188400738641426, + 13792950671402095073 + ], + [ + 9310952691940114113, + 4820182619662404377, + 9479969369442954044, + 8512369778696933060 + ], + [ + 16946138649176650488, + 9475913097060757863, + 6608972026504748865, + 7215353463715689998 + ], + [ + 349222139041408316, + 1507489261015035841, + 7596560681014222842, + 8808235055298411214 + ], + [ + 8007370340350072341, + 2549612240734498963, + 105233771877650291, + 8758305155554767568 + ], + [ + 17190433766023179459, + 1755290160765045579, + 5619893747453895498, + 9139477571875211116 + ], + [ + 15755591792726495281, + 17501027650687476798, + 5579351800673089158, + 5931628352091930640 + ], + [ + 7269556889579729096, + 8636006399519326592, + 15556402257631967994, + 12423945489648480054 + ], + [ + 6411602498376025591, + 16377643789139599240, + 1264958035077382258, + 16706608130239118866 + ], + [ + 14246313207191082462, + 2201136836754342130, + 12301078636732201867, + 10991169525653220176 + ], + [ + 2101214821629968022, + 11996351959015322539, + 15461759537099893272, + 5820786797852667153 + ], + [ + 10546547765646585412, + 16670337245061195679, + 14026017154393171841, + 15865302123450709636 + ], + [ + 14546229884213013754, + 1736742091912698149, + 9563343697509131991, + 15957923614096898715 + ], + [ + 10053685874691243725, + 4837706724113512400, + 2806343138575002644, + 1217140278849814125 + ], + [ + 1445801437405723985, + 16370378782744105412, + 14937074551650631907, + 9349528097788576916 + ], + [ + 313624596753562026, + 2737902703720676400, + 1491628534561577719, + 4958865646973460786 + ], + [ + 4749220647213961766, + 1523283588343260013, + 14435216093380418825, + 12058673416937256217 + ], + [ + 12221430523773573392, + 2119312783391782040, + 113666136908336034, + 5557001496562966971 + ], + [ + 8943540790257615175, + 15963411684352909178, + 12833466372967679781, + 16755820399299554647 + ], + [ + 10568513175105063273, + 8152439411055527457, + 13191469024927433668, + 16583335250317103083 + ], + [ + 8728976170665901948, + 12047344511237318236, + 2665537844838432218, + 17220904479682973198 + ], + [ + 9924606303320583729, + 15168541434821629608, + 15267127988736394576, + 4612730729137963542 + ], + [ + 15187295020445613202, + 10979580190616738578, + 2487576517666265788, + 7799526392944971411 + ], + [ + 14001553124798608592, + 983427750240831173, + 10498633617369923042, + 15506856636873354247 + ], + [ + 9695584132680310661, + 15058940491468263542, + 16902767176197422459, + 4307070711535476522 + ], + [ + 16170129192711277380, + 15594325905653564554, + 8589261531750893019, + 16380506012444184509 + ], + [ + 1298482137029698068, + 7046350962355653091, + 4851290198964994943, + 9583994567704854822 + ], + [ + 12002196043506075596, + 6568364019768992619, + 2982180816490272604, + 11005221893883916442 + ], + [ + 11195444762924129211, + 4080035169749061493, + 12552903944803877103, + 1737834024116304977 + ], + [ + 14989371064091658414, + 7021573041416327989, + 10313274026717983047, + 12022812057768375145 + ], + [ + 4605818886224729183, + 1445887803225464457, + 10940822604464014966, + 9884898953608657154 + ], + [ + 16595525430044003662, + 4052207436631314262, + 10293047811043558578, + 12338411972889057265 + ], + [ + 17022547446139753073, + 10651710177937554340, + 6940830771318907626, + 6641453047926556761 + ], + [ + 10509711725088536487, + 4962100381463002257, + 770256729671337313, + 5857473086438310769 + ], + [ + 13267845343537121240, + 12321261427265206453, + 7120567552214639265, + 17302478469072029437 + ], + [ + 15157833123384882226, + 8158551777234184706, + 12348570826200339644, + 14734791159756873167 + ], + [ + 3385809684799950973, + 12900259269431347094, + 17672545490781962423, + 8013657472810936941 + ], + [ + 9546288143416776531, + 8356139039634733121, + 17477514712681213981, + 9515108802170635886 + ], + [ + 15455406291521834876, + 18083571768045422071, + 2009769659787731673, + 7263333966403015872 + ], + [ + 61130843037975416, + 18121830552682131571, + 9667884638217866764, + 6932529860678316702 + ], + [ + 15509823136620654552, + 6676934950708893059, + 13351533805402596549, + 14340984679679191575 + ], + [ + 15880919573481609124, + 14836853565796210968, + 15058034487233879726, + 11000215022533975317 + ], + [ + 10611445668418674805, + 9013654201900818768, + 1617123938865368568, + 16484766808972651318 + ], + [ + 13652743593752436493, + 13843264938563223779, + 10417182020840583510, + 16106479734523413326 + ], + [ + 17003899699844258217, + 17283344455088140068, + 17379245612757089745, + 1779134255761065541 + ], + [ + 11263035503709897880, + 1042839549428969974, + 6638626002246118718, + 1733549590874866310 + ], + [ + 13054247239013491523, + 14047141927303128296, + 2417752406294216107, + 5255181314162279551 + ], + [ + 1784021430104795099, + 3912913366054617723, + 8208877227749479136, + 4259205675774136108 + ], + [ + 801501735568309733, + 3220301656144181340, + 6144806934797449899, + 10479314068206076631 + ], + [ + 864619228795552444, + 2705960387071331097, + 15702747436396598972, + 14131926486457006694 + ], + [ + 15349058561965444062, + 16738574548455051915, + 4609208407223910426, + 11352062762791244662 + ], + [ + 16513285945090237658, + 6443875617703638442, + 17271016792575259072, + 426511686464611712 + ], + [ + 13863640462921288570, + 3362196992389213358, + 3576502768827883720, + 49219399301262346 + ], + [ + 14852014958673205840, + 11855705779815876870, + 8141476064801289266, + 15234506534160954104 + ], + [ + 6292328028167907211, + 6280576736728723621, + 1814915348986377963, + 3167789754322444841 + ], + [ + 6093870088272451581, + 12912333461662707605, + 16038365026642624017, + 10037265733136426182 + ], + [ + 5658473063427008398, + 18194712009700816671, + 3316188885192160812, + 15032222957557455487 + ], + [ + 10746739009272326386, + 4381896503060636995, + 13390900032103397758, + 11290296227744685851 + ], + [ + 7946268274905655961, + 12464655577446728520, + 3476152367809517039, + 3103729420470642525 + ], + [ + 15652670185218353632, + 17922284652588341925, + 3502474425690015164, + 3577240886292713575 + ], + [ + 13130871911189865405, + 2598654314674217849, + 6130707868677033708, + 11318789126458218054 + ], + [ + 14442525432094720658, + 10861520212227307580, + 10308956417568414174, + 101391938116250123 + ], + [ + 8015353735581004985, + 11791356411393233202, + 15134704188872104026, + 2916434958525680154 + ], + [ + 17776268955107890735, + 3978578384988358930, + 7512482176825678493, + 4207030036138354730 + ], + [ + 4778990000266723258, + 12646326430153649418, + 15602744563429649630, + 13225673449752707138 + ], + [ + 9874615904187846642, + 785813436574501824, + 7422887093860615814, + 12575067740028803899 + ], + [ + 2168314129068013776, + 5876170257821873353, + 6574425448964925595, + 13006818379253162445 + ], + [ + 18203396842093379784, + 1637929000957737331, + 16472903772026963266, + 10222221849709050007 + ], + [ + 8175241234035594021, + 11131701218615583700, + 2590544239124773213, + 13103205380700956240 + ], + [ + 10265760611171832222, + 10772001381712818941, + 9769892419500727073, + 3757944212165946207 + ], + [ + 12890674101364520820, + 17436315026775313277, + 17685632275460283213, + 11597862884205200021 + ], + [ + 6541476428026208530, + 1572664979326233234, + 7220008363221767753, + 5030515443926464143 + ], + [ + 1736392533925503753, + 4028348047388923757, + 1322644146499193870, + 7899110541856172042 + ], + [ + 824249951832333568, + 3650442342240934725, + 9551872020421810878, + 4459093260544332906 + ], + [ + 4897538583957298940, + 9763535759998548001, + 17962120881583547780, + 16423532894596203353 + ], + [ + 15621981029420175013, + 12716027808121583594, + 5698997410684688521, + 14893034348453337964 + ], + [ + 57123003983559085, + 1764189019842202487, + 12021079431755992353, + 4611397927843211028 + ], + [ + 11271204071286517021, + 11016763947620063917, + 10240257375147160558, + 6936015967868091242 + ], + [ + 13263159746058683924, + 2115544844352440396, + 17037308825725243672, + 15392971905394245550 + ], + [ + 3040132672294734369, + 8799577028392802142, + 4698252977355096983, + 12029143421110018733 + ], + [ + 3367138533962530706, + 11052858577054708144, + 13777717310915519372, + 1118835749836496249 + ], + [ + 18247935773305597594, + 4791613470261596504, + 2831278673598556804, + 13054754323096013606 + ], + [ + 16660028838922677973, + 9396606308613201784, + 10417460426584440111, + 8380249813777095858 + ], + [ + 8666375557464313815, + 6304275044317841466, + 17005733772133350822, + 14343984316653970581 + ], + [ + 6123226050306352446, + 17155936354664339685, + 8617663439980301335, + 15168460408431057703 + ], + [ + 4711490317757564870, + 4007952793500570494, + 1619724888362180342, + 135640370275358583 + ], + [ + 3568489405188009952, + 10063008786740635782, + 3645030669998184283, + 11251876386972219611 + ], + [ + 8493411482257270591, + 2420069605766207080, + 4319637578909518850, + 7366398383772225801 + ], + [ + 10514279907222008963, + 4576784878418470993, + 13703409256143697610, + 12595458216589602418 + ], + [ + 6518196967791403281, + 6267315352755318878, + 17017845178414282191, + 6219869337455185408 + ], + [ + 9419176152740350408, + 7255025946876060056, + 13692775553690785222, + 6482964045212267647 + ], + [ + 10371771524251272238, + 7264554963155886115, + 11851596230763322123, + 9644034659422561803 + ], + [ + 16478128758974022864, + 10586973455001136017, + 10940854718906381238, + 4322569144361190672 + ], + [ + 1408324526595066767, + 8225966379387133915, + 575234437450946120, + 4532159296152332514 + ], + [ + 14713730919085929141, + 8299030584912591200, + 12653081274697230155, + 7281510145820913452 + ], + [ + 13065256168386635886, + 11725981090441231815, + 9241488846717901227, + 2660860847185625194 + ], + [ + 17344786539017984359, + 16667262327893622443, + 2245517842543022928, + 5289295469095289187 + ], + [ + 7712996453163241402, + 13291387059438293554, + 15475873660461985862, + 421113001330390910 + ], + [ + 6600556276994686684, + 15236925279661890975, + 9085425445873596043, + 13489979627098239874 + ], + [ + 16522817509787049424, + 7880119001244729499, + 2065132977854154043, + 13961595284131100852 + ], + [ + 10136466656472241068, + 7462847284592418995, + 5211060891495522982, + 3429812446680794228 + ], + [ + 1290650595638649346, + 13577818566931833714, + 2388552128026682549, + 13062451014076475307 + ], + [ + 6070278064232182539, + 12399409837026713208, + 7006572737093555522, + 15229533042676039053 + ], + [ + 4546934482854074283, + 12178466512696871783, + 1691876649621188863, + 11473100481876466355 + ], + [ + 1236556729692669368, + 5549499687074217624, + 5958432331744161923, + 17960851426383425726 + ], + [ + 11313384441935481196, + 506230122531558484, + 17480105233549292653, + 3497216050489019068 + ], + [ + 14180330000703954943, + 17537654316605413864, + 13893109338811179145, + 12773435230801104558 + ], + [ + 1789329554161917105, + 3821166735342421302, + 492899993274707886, + 12499398353307226422 + ], + [ + 3089012429777109607, + 10341877957962585240, + 7745611914889843192, + 7156440096296115871 + ], + [ + 14047653524331542619, + 14986552290847971271, + 8344707263938736217, + 5768162811052933747 + ], + [ + 3282503115484594392, + 3455102204735354908, + 6152707383721113591, + 17881334209336571790 + ], + [ + 6895592993382091339, + 14944664838702526606, + 14158277091240311047, + 13527182248087302901 + ], + [ + 3709694612749923839, + 2612160447494745836, + 1406956200130224054, + 1366284088614500522 + ], + [ + 9948565747047514924, + 7052268914527763961, + 18019747825808196928, + 14284818641981927036 + ], + [ + 3586214080877747437, + 18259935751422321449, + 7615481956713457290, + 14815795422370035012 + ], + [ + 127402153735286355, + 14056365981282611643, + 13874770993027970720, + 619630456240824192 + ], + [ + 14160230678035047748, + 5889480608083619036, + 7255863117098942211, + 15199656156616971091 + ], + [ + 3095946492180700178, + 4006392168790405864, + 6879209997262175243, + 299198988833119182 + ], + [ + 7324876720724904977, + 16163169761447383767, + 12506750534396872240, + 2471214392724636123 + ], + [ + 9097827375986012190, + 14565705700237004602, + 14313871429102448506, + 11871591868576605558 + ], + [ + 9799079875206163527, + 16651435323107739422, + 12479220145998529239, + 3293893419326195678 + ], + [ + 10308258292354323463, + 12348814193023657478, + 7617037745166680507, + 4395321161975898727 + ], + [ + 5350571522462508856, + 13168312859432101164, + 16051585591307343397, + 14229124174436500603 + ], + [ + 7166265506509230502, + 7161154874163920078, + 8397077088165043439, + 11599821267858973994 + ], + [ + 7480649953471058826, + 10095090134750662786, + 10564643199160392009, + 13520621355659318250 + ], + [ + 10857779123272725120, + 15686674254635154618, + 8867730228951457290, + 10801878621148582310 + ], + [ + 15060256657026761959, + 9661131710054923901, + 672914961534049680, + 12834176932586128630 + ], + [ + 949448556211506716, + 15381404281513795275, + 11155631745566842701, + 2704703395424058389 + ], + [ + 9515248836992226419, + 8107063249314601218, + 7169007343668853680, + 4398533039543530267 + ], + [ + 5048521287079394266, + 469091126174822039, + 15224036421670482877, + 2109812614761568090 + ], + [ + 16374381239073062350, + 1415659237932604676, + 15755278916993952324, + 4477381067900828660 + ], + [ + 5908643369108814128, + 16993840892601214320, + 9745154490046936812, + 12675544964328790510 + ], + [ + 13069705042519055121, + 114347527485448732, + 13607966080279761362, + 3198027414138631154 + ], + [ + 2126201229935790021, + 11762486874095747924, + 4405447136645256490, + 4546150485765128281 + ], + [ + 11517522298498019347, + 9683562397139382420, + 17997189851623366056, + 15075626419278367114 + ], + [ + 17300749044902256514, + 13180322067670835054, + 13510754977375972746, + 16789287824862069583 + ], + [ + 12482184120647536152, + 6673581288163589602, + 12763923036507066435, + 14094147320392535720 + ], + [ + 14259634259170511729, + 4875730172347810212, + 84468584086030163, + 8303744294867418687 + ], + [ + 12134644548742181831, + 8520649738990136053, + 16059641390155564470, + 5416979754786543764 + ], + [ + 2092318536537973522, + 11767101658840205425, + 6426865564773940591, + 14647807617379392454 + ], + [ + 450267335414320409, + 9743488482513949727, + 60939637019009091, + 17766639401038188429 + ], + [ + 10940698167282175513, + 14751185897733548414, + 12951179730146965260, + 10875205992060835228 + ], + [ + 13364210655207872649, + 6433202412249539021, + 9336639704508334838, + 13505754981533474450 + ], + [ + 13696994814871272283, + 4490009507613100808, + 13804331039068475494, + 5468505803402562249 + ], + [ + 4777271447313491592, + 9940020440702119485, + 1101181637482946058, + 644606693604161858 + ], + [ + 15097959041405784257, + 12307130809829041484, + 17258499521253983865, + 10749514694060779271 + ], + [ + 10190208760039486310, + 4226050742652743727, + 8941293745652956008, + 16590522505585423775 + ], + [ + 345192297192706835, + 446809322130030426, + 14301758245246751976, + 9719056934946360728 + ], + [ + 12881116110058824616, + 9527685388634025534, + 11091584611747550280, + 17824266919172201804 + ], + [ + 1574239507079237453, + 8582461342969153012, + 12264251495254783586, + 17637680562426650364 + ], + [ + 10192143269632239849, + 13007991288866360616, + 15140175217087410009, + 12752906480866993968 + ], + [ + 1870988781431107523, + 12976682012942521853, + 16429062848935476734, + 5798003006437035985 + ], + [ + 14584766751103981854, + 17047930049374537599, + 16615811923791215213, + 4382675641211926136 + ], + [ + 2714557854446349417, + 7104188094330759435, + 4252584297915226480, + 8214575447584991866 + ], + [ + 11055975993893155083, + 4263965260378501220, + 14890629048371839452, + 12114106467257211085 + ], + [ + 1696215674801501046, + 2266423673248165355, + 17663731467117251495, + 3131727223950690444 + ], + [ + 9538270027605424981, + 14695627410990929758, + 1100103051852107643, + 7780696685697285282 + ], + [ + 3640909033400638252, + 4685184407249885115, + 1159593584695683466, + 5810155451150284456 + ], + [ + 2142365296746734893, + 15072293834204351367, + 10906328353503930623, + 567086761313849045 + ], + [ + 16792244974449676806, + 5281042885555694958, + 803668749758477336, + 9632569928427671141 + ], + [ + 11458024915503659884, + 12163640565717382175, + 5426693528062973190, + 5318451835514658298 + ], + [ + 17468129298890753615, + 16365877952312079431, + 4255216049796249864, + 17519162521801620751 + ], + [ + 16881958987441626136, + 5348165195536725074, + 1110205049250373278, + 3270960662287149636 + ], + [ + 1226689297335858879, + 5569006707448968175, + 12862213669554513549, + 13476251685033412618 + ], + [ + 17469709307599228055, + 10239286546577328519, + 11089348310818650527, + 16456908862000481769 + ], + [ + 1488822551903623063, + 1027724056630207939, + 17697306299429716060, + 16855149560650760331 + ], + [ + 6973362373999440967, + 10660889882557485296, + 10425405668156759777, + 6301066711999204638 + ], + [ + 414734469595850357, + 14255487988571755338, + 8593074929345797359, + 16605827151888774599 + ], + [ + 16875797800314241514, + 12421815564591930411, + 2652019482537730851, + 6038511721575984408 + ], + [ + 5083130506118840282, + 10236076700696608757, + 89798661707215807, + 11047945556430945234 + ], + [ + 9052849932438286930, + 766869919370273028, + 9513938692410545262, + 9325822678740812785 + ], + [ + 12214954222172122496, + 2137993706327729295, + 9068121284446752470, + 16719368474204358065 + ], + [ + 12846496216910539260, + 14961944612175511231, + 4871177192578157967, + 871092876547424272 + ], + [ + 8432570778385641968, + 16742266319428376459, + 5202631662503988626, + 9179077767480984950 + ], + [ + 6907086971366422845, + 3630230185711868320, + 6363326632303072661, + 2155376917773117715 + ], + [ + 7260111458604834720, + 15869987976273960274, + 5471864801301693834, + 6186332987204233992 + ], + [ + 7579472070725254127, + 4175627325036864033, + 2726864388901619006, + 17182366690618521544 + ], + [ + 10366850615209571638, + 594983328964439422, + 5708701194817491298, + 8320252948121397632 + ], + [ + 7681701787398279771, + 8922827186766353002, + 16390646056989747875, + 16861016347708202354 + ], + [ + 18349539097929417681, + 11011444774390028397, + 14929165998832565332, + 4785028369071377058 + ], + [ + 12474665121325276393, + 6203136048752329670, + 8857782650797383532, + 1205842604249274162 + ], + [ + 4986065786927816995, + 16774907198741044886, + 3781179129421387661, + 10415439284245950953 + ], + [ + 11574881136629381449, + 12379735189792408408, + 16543138864606381298, + 2352837174543239308 + ], + [ + 2755808935111250351, + 11413691641496289631, + 7433067894962399074, + 9263092778396333619 + ], + [ + 510815690565069916, + 1326078112306964442, + 2280931398968953373, + 16372347667232436246 + ], + [ + 13049250986319352420, + 1312888884206484061, + 5191125907416704942, + 12910692959434040696 + ], + [ + 12641131533859353693, + 806990755667531292, + 8339582499246533062, + 15459494525405539126 + ], + [ + 5334506198163160487, + 12788298331318017466, + 3878039519170214619, + 14733573925349283487 + ], + [ + 5190557862976962645, + 13714749928322729293, + 10374841881342744627, + 15288181470367912639 + ], + [ + 16231478233162755783, + 12802076246758748329, + 14761367109514758527, + 14411193599867587859 + ], + [ + 8198731374774297764, + 3230920736551397516, + 11406632512199098782, + 10984385724696684374 + ], + [ + 2230082119129443391, + 15626857176238648658, + 10525636546408036753, + 713830293126230928 + ], + [ + 4947353515945045110, + 14890750024678328507, + 11992121003625623155, + 9247439145474008589 + ], + [ + 2476255618728017726, + 12423839440278091466, + 11131574346213868564, + 15878857548422208415 + ], + [ + 14063080495591128251, + 17832973426635180302, + 16234044432643152520, + 3790040177800561340 + ], + [ + 17654367747593125286, + 14771556851404254590, + 7054247606189603403, + 16389491650139306501 + ], + [ + 16945878684828151504, + 3218677612764542854, + 4129066622553533042, + 12411143505986390453 + ], + [ + 18139421373310678346, + 12565918292252415379, + 15834446535016534449, + 6148063108469358612 + ], + [ + 12292679265601130740, + 13386299384345137465, + 13364501573803460934, + 8733289102497600737 + ], + [ + 6160628888236701076, + 812243480588759160, + 13247424403141713486, + 10099500208290322254 + ], + [ + 10969580462260030094, + 16960852675866882693, + 14194600920049272873, + 2806447904271636378 + ], + [ + 5308612537476412691, + 2017232117327961782, + 4894043882170046108, + 7279530397891640384 + ], + [ + 4144733560007592583, + 5771344498053405563, + 15232642512723560772, + 17432794023851843115 + ], + [ + 13083133801966421336, + 6640909047775641455, + 7780326336877273740, + 3087015496142074629 + ], + [ + 4093431377560277258, + 11212918479165511440, + 8471957796338043904, + 10134266515436065987 + ], + [ + 7717602192687906239, + 16498238127262085325, + 2796866393834457756, + 6080730252731365434 + ], + [ + 15198975112515001105, + 3427384774999580491, + 9100144446909554927, + 12939101842468805683 + ], + [ + 3513270711153070627, + 6760090775854266850, + 2266114679123970134, + 2453164217927145379 + ], + [ + 8454909244339253322, + 3937159550392777548, + 17092850706817714179, + 14355781411083550660 + ], + [ + 14878805576521609961, + 14710363931287834639, + 3026158727470434848, + 664513313042659381 + ], + [ + 8491751794767535837, + 13990906406579930747, + 10128524312616192734, + 11329057191619161908 + ], + [ + 14453858867510385195, + 7990714203132759977, + 5706371533563158927, + 4128865490009717707 + ], + [ + 7793399965923611298, + 13429890700846305668, + 6463577189314693043, + 1403793223780405881 + ], + [ + 14506683092001193039, + 2676502583153744002, + 432387115071868059, + 5324230977146090619 + ], + [ + 5163412501615965388, + 13723489526376938207, + 13122017355634831416, + 9867447233188068220 + ], + [ + 2169005641163984550, + 9186165665928554404, + 17910278673295197365, + 11381918494994166306 + ], + [ + 5758488670302072688, + 18181832326798847807, + 10253561012448568621, + 6796662601196927726 + ], + [ + 15384372095875884299, + 15758325895562962606, + 979979951038690002, + 4884709252008623452 + ], + [ + 9658033725016409161, + 11061216333798295999, + 10656853269529126466, + 10494481123210514991 + ], + [ + 10565302142069456280, + 4482395191206056917, + 1026499487185603956, + 7313927946426328835 + ], + [ + 914075172237814299, + 4712333083011398137, + 5903513285138462152, + 27234332817070790 + ], + [ + 6165097805071238615, + 12405114942064306895, + 644764352603959519, + 9890780672007958877 + ], + [ + 15139300154181340570, + 3763515407393500498, + 747278468332165545, + 12401993133389174873 + ], + [ + 1560524376846745097, + 4692895970840561536, + 8733218268882211058, + 11050746819680980390 + ], + [ + 2481724169828996194, + 13708290945708520871, + 4344699263192501279, + 7140288180697285542 + ], + [ + 296768972336373070, + 10813546555235346490, + 16170115378690748299, + 12802703395795280191 + ], + [ + 14251656741089442088, + 4214370918062569580, + 10032045984805229135, + 10373930023291015419 + ], + [ + 17093829866009459220, + 12859940170163163826, + 18210851741109329458, + 16336121553624015019 + ], + [ + 4407838941860440582, + 11854162025145257857, + 12199975997855699065, + 2502264419023857875 + ], + [ + 12466276041107521420, + 5321886014476179588, + 7215900333286173827, + 6244069735947509039 + ], + [ + 5660993473650802623, + 11420246285415070761, + 4658057095848491886, + 6674509485613885322 + ], + [ + 16443753989364975722, + 553371339109155814, + 6176240530340905521, + 5112633271096324804 + ], + [ + 17344015413911877127, + 17921285748955845167, + 472207513366524064, + 9508903352311585055 + ], + [ + 2373580342727259876, + 17626197481532596235, + 5443748763702275935, + 16239948710647217063 + ], + [ + 1893590215294085348, + 16922448579707654020, + 3562803535149926022, + 5008057946422210179 + ], + [ + 9528486283906265098, + 16540897732900210948, + 7987610981843235045, + 8503796247003141361 + ], + [ + 7151582572260738324, + 8798367050545135378, + 17208414855521381994, + 16950417755338618580 + ], + [ + 16098392335079248174, + 15218667139563807688, + 3579977320329860139, + 5640122365751888962 + ], + [ + 9584075531015381817, + 16275032664923657166, + 13987470479712899701, + 2201274726914907785 + ], + [ + 9927398107804295577, + 5687396867124688978, + 10639332412514046012, + 10390174472889436172 + ], + [ + 7906944927470502930, + 9629467849018808831, + 16716405557811073978, + 2687565502976952246 + ], + [ + 2357326643063601119, + 12372080030488676843, + 17862973568880540528, + 9758076484635237383 + ], + [ + 6955909340644692347, + 9788637714503672561, + 10015565612607022102, + 5622624961359105679 + ], + [ + 8476474886341847071, + 14658488683343597259, + 14961921379651609802, + 14123545985510427091 + ], + [ + 1388357604146037902, + 15713286211316016536, + 5612470285625982657, + 6487364037172184435 + ], + [ + 15189267229737199628, + 6502744762576006736, + 13803864300857374808, + 5415597147102054081 + ], + [ + 11784930967835797340, + 11401415610557072973, + 1534900691166631710, + 4724373879472771719 + ], + [ + 10801273164646452905, + 11959510535773071656, + 13440563277297614072, + 11732355214966685480 + ], + [ + 709242285317259075, + 14093566268118334778, + 17068650979174969466, + 14497803119243527377 + ], + [ + 1887862044793269490, + 8537802901513975848, + 1791222441789963991, + 9563652556460700888 ] - } + ] } \ No newline at end of file diff --git a/prover/data/keys/verification_compression_wrapper_1_key.json b/prover/data/keys/verification_compression_wrapper_1_key.json new file mode 100644 index 000000000000..7962a007a353 --- /dev/null +++ b/prover/data/keys/verification_compression_wrapper_1_key.json @@ -0,0 +1,260 @@ +{ + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 52, + "num_witness_columns": 78, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 65536, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 43116 + ], + [ + 1, + 43116 + ], + [ + 2, + 43116 + ], + [ + 3, + 43116 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "fri_lde_factor": 2, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 11089233109673513909, + 4694567683723191950, + 2252594152558732892, + 328970513026299243 + ], + [ + 13110006211642469395, + 294375540944797602, + 16182235873004377367, + 2953023061901047966 + ], + [ + 12954993379135284962, + 6922678615292520290, + 17867758875593058615, + 339647768012530579 + ], + [ + 12809050784791995014, + 16689513786002107471, + 11773267927233763048, + 2032047837067080396 + ], + [ + 7271809219891052194, + 5444455652423618380, + 1935299370455922934, + 3289711575126119664 + ], + [ + 11181297440700596994, + 10603106417644946600, + 665809790647260411, + 187324941596609709 + ], + [ + 9724160063639293155, + 1608086271555753498, + 16260908485634719227, + 632759144306004522 + ], + [ + 16171710219953295253, + 11735348771071823498, + 13328414849155243388, + 388220022403515252 + ], + [ + 6347515368180647794, + 3011684189305320549, + 17039076561062895245, + 2001704612642658194 + ], + [ + 3707095019654850078, + 11362163228164094076, + 1561353676808431273, + 3424316751369411482 + ], + [ + 716932689692970095, + 18233950677301858032, + 17408689052397185323, + 2942664824563666170 + ], + [ + 12477682224945956203, + 420380906955838894, + 12174965353807932632, + 2912634883207646728 + ], + [ + 17124977403072675, + 18022072095965759474, + 364660436009892494, + 3385316467253708000 + ], + [ + 16889669530683164245, + 523943222152237493, + 1642074572079780044, + 993946077205588770 + ], + [ + 4746369334258751576, + 10488207333534533554, + 13843593047124360807, + 1554413355203877957 + ], + [ + 674378918528041149, + 9245737942013154408, + 5431441209257727894, + 970073226355719652 + ] + ] +} \ No newline at end of file diff --git a/prover/data/keys/verification_compression_wrapper_5_key.json b/prover/data/keys/verification_compression_wrapper_5_key.json index 8dd3feeabf37..b9a682b5ed3b 100644 --- a/prover/data/keys/verification_compression_wrapper_5_key.json +++ b/prover/data/keys/verification_compression_wrapper_5_key.json @@ -1,240 +1,238 @@ { - "CompressionMode5Circuit": { - "fixed_parameters": { - "parameters": { - "num_columns_under_copy_permutation": 28, - "num_witness_columns": 0, - "num_constant_columns": 4, - "max_allowed_constraint_degree": 4 - }, - "lookup_parameters": "NoLookup", - "domain_size": 131072, - "total_tables_len": 0, - "public_inputs_locations": [ - [ - 0, - 102321 - ], - [ - 1, - 102321 - ], - [ - 2, - 102321 - ], - [ - 3, - 102321 - ] + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 28, + "num_witness_columns": 0, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 4 + }, + "lookup_parameters": "NoLookup", + "domain_size": 131072, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 102321 ], - "extra_constant_polys_for_selectors": 4, - "table_ids_column_idxes": [], - "quotient_degree": 8, - "selectors_placement": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 4, - "num_constants": 1, - "degree": 7, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 7, - "num_constants": 4, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 1, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 8, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + [ + 1, + 102321 + ], + [ + 2, + 102321 + ], + [ + 3, + 102321 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 1, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 5, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 9, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 11, - "num_constants": 4, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 0, - "num_constants": 4, - "degree": 1, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 11, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false } } } } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 6, - "num_constants": 2, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 10, - "num_constants": 0, - "degree": 0, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 10, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false } - } - }, - "right": { - "GateOnly": { - "gate_idx": 3, - "num_constants": 0, - "degree": 1, - "needs_selector": true, - "is_lookup": false } } + }, + "right": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 0, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } } - }, - "right": { - "GateOnly": { - "gate_idx": 2, - "num_constants": 0, - "degree": 1, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 1, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "fri_lde_factor": 512, - "cap_size": 8 + } }, - "setup_merkle_tree_cap": [ - [ - 16914330110517127429, - 16187587722999224490, - 18023818126147572005, - 2874604292345707728 - ], - [ - 16768425182336866443, - 12214564422923037261, - 13582724864735257774, - 1643211286062672867 - ], - [ - 15218535791823658828, - 14934144541713644491, - 5667321981618564549, - 961076974096461270 - ], - [ - 12538243484307626811, - 154885234119673688, - 6664593122905080257, - 3057958811251130407 - ], - [ - 12286013330322000138, - 5761148084208728264, - 2870132557697656188, - 1515812049810917361 - ], - [ - 12416599860285890728, - 16995984316626848023, - 6201310732706348436, - 3434944201786144260 - ], - [ - 2716626386491435001, - 128784567533803364, - 15547067112370735343, - 1561596902164897368 - ], - [ - 8739964537157479045, - 17599924720345455572, - 12386657679573206086, - 835122317104749492 - ] + "fri_lde_factor": 512, + "cap_size": 8 + }, + "setup_merkle_tree_cap": [ + [ + 16914330110517127429, + 16187587722999224490, + 18023818126147572005, + 2874604292345707728 + ], + [ + 16768425182336866443, + 12214564422923037261, + 13582724864735257774, + 1643211286062672867 + ], + [ + 15218535791823658828, + 14934144541713644491, + 5667321981618564549, + 961076974096461270 + ], + [ + 12538243484307626811, + 154885234119673688, + 6664593122905080257, + 3057958811251130407 + ], + [ + 12286013330322000138, + 5761148084208728264, + 2870132557697656188, + 1515812049810917361 + ], + [ + 12416599860285890728, + 16995984316626848023, + 6201310732706348436, + 3434944201786144260 + ], + [ + 2716626386491435001, + 128784567533803364, + 15547067112370735343, + 1561596902164897368 + ], + [ + 8739964537157479045, + 17599924720345455572, + 12386657679573206086, + 835122317104749492 ] - } + ] } \ No newline at end of file diff --git a/prover/data/keys/verification_scheduler_key.json b/prover/data/keys/verification_scheduler_key.json index 8a52cc244bac..bda175b7e18c 100644 --- a/prover/data/keys/verification_scheduler_key.json +++ b/prover/data/keys/verification_scheduler_key.json @@ -1,270 +1,268 @@ { - "SchedulerCircuit": { - "fixed_parameters": { - "parameters": { - "num_columns_under_copy_permutation": 130, - "num_witness_columns": 0, - "num_constant_columns": 4, - "max_allowed_constraint_degree": 8 - }, - "lookup_parameters": { - "UseSpecializedColumnsWithTableIdAsConstant": { - "width": 3, - "num_repetitions": 4, - "share_table_id": true - } - }, - "domain_size": 1048576, - "total_tables_len": 132096, - "public_inputs_locations": [ - [ - 0, - 1043851 - ], - [ - 1, - 1043851 - ], - [ - 2, - 1043851 - ], - [ - 3, - 1043851 - ] + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 130, + "num_witness_columns": 0, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": { + "UseSpecializedColumnsWithTableIdAsConstant": { + "width": 3, + "num_repetitions": 4, + "share_table_id": true + } + }, + "domain_size": 1048576, + "total_tables_len": 132096, + "public_inputs_locations": [ + [ + 0, + 1043851 ], - "extra_constant_polys_for_selectors": 4, - "table_ids_column_idxes": [ - 8 + [ + 1, + 1043851 ], - "quotient_degree": 8, - "selectors_placement": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 1, - "num_constants": 0, - "degree": 7, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 4, - "num_constants": 4, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "Fork": { - "left": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 5, - "num_constants": 1, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 6, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + [ + 2, + 1043851 + ], + [ + 3, + 1043851 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [ + 8 + ], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 1, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 2, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 7, - "num_constants": 0, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 9, - "num_constants": 4, - "degree": 2, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 0, - "num_constants": 4, - "degree": 1, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false } } } } - }, - "right": { - "Fork": { - "left": { - "GateOnly": { - "gate_idx": 3, - "num_constants": 2, - "degree": 3, - "needs_selector": true, - "is_lookup": false - } - }, - "right": { - "GateOnly": { - "gate_idx": 8, - "num_constants": 0, - "degree": 0, - "needs_selector": true, - "is_lookup": false - } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false } } } } } } - }, - "fri_lde_factor": 2, - "cap_size": 16 + } }, - "setup_merkle_tree_cap": [ - [ - 9887208323851505217, - 1123001217986730435, - 343259880253311786, - 2151140818520262118 - ], - [ - 12495904531249642919, - 17232615797756148395, - 3335544159309667561, - 6261962261160675850 - ], - [ - 3290174806954782361, - 3957604867997030178, - 12129129725630125865, - 1636089896333385634 - ], - [ - 14645858759272203991, - 11653487901803110416, - 2499237237036147984, - 1841727833267838231 - ], - [ - 18193008520821522692, - 14508611443656176962, - 15201308762805005611, - 16051075400380887227 - ], - [ - 4504987266706704494, - 7397695837427186224, - 10067172051000661467, - 5044520361343796759 - ], - [ - 9408005523417633181, - 14924548137262927482, - 8927260223716946348, - 25087104176919469 - ], - [ - 11857324568001808264, - 5783626311717767938, - 10769426771780222703, - 8523712547334248178 - ], - [ - 18394924697039022030, - 3773697459649116941, - 6013511991919985339, - 17810626771729638933 - ], - [ - 13290121767754155136, - 11225142773614876536, - 4764911669339622945, - 17476639133556434478 - ], - [ - 11822797557540925718, - 17521847674855164779, - 18126641713175128985, - 3215884914057380988 - ], - [ - 15220380051263546850, - 7948573237324556416, - 264360501330239312, - 16455579027557250339 - ], - [ - 17738768733790921549, - 4021891743990340907, - 17352941271057641152, - 15584530612705924787 - ], - [ - 7157587680183062137, - 8837818432071888650, - 16467824236289155049, - 17557580094049845697 - ], - [ - 15526977922222496027, - 5885713491624121557, - 8813450728670527813, - 10234120825800411733 - ], - [ - 12554317685609787988, - 4789370247234643566, - 16370523223191414986, - 9108687955872827734 - ] + "fri_lde_factor": 2, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 9887208323851505217, + 1123001217986730435, + 343259880253311786, + 2151140818520262118 + ], + [ + 12495904531249642919, + 17232615797756148395, + 3335544159309667561, + 6261962261160675850 + ], + [ + 3290174806954782361, + 3957604867997030178, + 12129129725630125865, + 1636089896333385634 + ], + [ + 14645858759272203991, + 11653487901803110416, + 2499237237036147984, + 1841727833267838231 + ], + [ + 18193008520821522692, + 14508611443656176962, + 15201308762805005611, + 16051075400380887227 + ], + [ + 4504987266706704494, + 7397695837427186224, + 10067172051000661467, + 5044520361343796759 + ], + [ + 9408005523417633181, + 14924548137262927482, + 8927260223716946348, + 25087104176919469 + ], + [ + 11857324568001808264, + 5783626311717767938, + 10769426771780222703, + 8523712547334248178 + ], + [ + 18394924697039022030, + 3773697459649116941, + 6013511991919985339, + 17810626771729638933 + ], + [ + 13290121767754155136, + 11225142773614876536, + 4764911669339622945, + 17476639133556434478 + ], + [ + 11822797557540925718, + 17521847674855164779, + 18126641713175128985, + 3215884914057380988 + ], + [ + 15220380051263546850, + 7948573237324556416, + 264360501330239312, + 16455579027557250339 + ], + [ + 17738768733790921549, + 4021891743990340907, + 17352941271057641152, + 15584530612705924787 + ], + [ + 7157587680183062137, + 8837818432071888650, + 16467824236289155049, + 17557580094049845697 + ], + [ + 15526977922222496027, + 5885713491624121557, + 8813450728670527813, + 10234120825800411733 + ], + [ + 12554317685609787988, + 4789370247234643566, + 16370523223191414986, + 9108687955872827734 ] - } + ] } \ No newline at end of file diff --git a/prover/rust-toolchain b/prover/rust-toolchain index 03c040b91f1f..bc5d1d6bbd8e 100644 --- a/prover/rust-toolchain +++ b/prover/rust-toolchain @@ -1 +1,2 @@ -nightly-2024-08-01 +[toolchain] +channel = "nightly-2024-08-01" diff --git a/prover/setup-data-gpu-keys.json b/prover/setup-data-gpu-keys.json index 8a3bdeb262c1..6ec6570c6fa9 100644 --- a/prover/setup-data-gpu-keys.json +++ b/prover/setup-data-gpu-keys.json @@ -1,5 +1,5 @@ { - "us": "gs://matterlabs-setup-data-us/dc3bba7-gpu/", - "europe": "gs://matterlabs-setup-data-europe/dc3bba7-gpu/", - "asia": "gs://matterlabs-setup-data-asia/dc3bba7-gpu/" + "us": "gs://matterlabs-setup-data-us/a5d7741-gpu/", + "europe": "gs://matterlabs-setup-data-europe/a5d7741-gpu/", + "asia": "gs://matterlabs-setup-data-asia/a5d7741-gpu/" } diff --git a/yarn.lock b/yarn.lock index 732577daeb68..eabdce369080 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2943,10 +2943,12 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== -"@types/node@18.15.13": - version "18.15.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" - integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== +"@types/node@22.7.5": + version "22.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== + dependencies: + undici-types "~6.19.2" "@types/node@^10.0.3": version "10.17.60" @@ -5487,18 +5489,18 @@ ethers@^5.0.2, ethers@^5.7.0, ethers@^5.7.2, ethers@~5.7.0, ethers@~5.7.2: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" -ethers@^6.7.1: - version "6.12.1" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.12.1.tgz#517ff6d66d4fd5433e38e903051da3e57c87ff37" - integrity sha512-j6wcVoZf06nqEcBbDWkKg8Fp895SS96dSnTCjiXT+8vt2o02raTn4Lo9ERUuIVU5bAjoPYeA+7ytQFexFmLuVw== +ethers@^6.13.5: + version "6.13.5" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.5.tgz#8c1d6ac988ac08abc3c1d8fabbd4b8b602851ac4" + integrity sha512-+knKNieu5EKRThQJWwqaJ10a6HE9sSehGeqWN65//wE7j47ZpFhKAnHB/JJFibwwg61I/koxaPsXbXpD/skNOQ== dependencies: "@adraffy/ens-normalize" "1.10.1" "@noble/curves" "1.2.0" "@noble/hashes" "1.3.2" - "@types/node" "18.15.13" + "@types/node" "22.7.5" aes-js "4.0.0-beta.5" - tslib "2.4.0" - ws "8.5.0" + tslib "2.7.0" + ws "8.17.1" ethers@~5.5.0: version "5.5.4" @@ -10791,10 +10793,10 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" @@ -11007,6 +11009,11 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + undici@^5.14.0: version "5.28.4" resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" @@ -11287,10 +11294,10 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== -ws@8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" - integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== +ws@8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== ws@^7.4.6: version "7.5.9" diff --git a/zkstack_cli/Cargo.lock b/zkstack_cli/Cargo.lock index cfc16535db50..58bd4ce4f1ee 100644 --- a/zkstack_cli/Cargo.lock +++ b/zkstack_cli/Cargo.lock @@ -628,6 +628,33 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" @@ -2143,6 +2170,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -7045,7 +7082,7 @@ dependencies = [ [[package]] name = "zkstack" -version = "0.1.0" +version = "0.1.2" dependencies = [ "anyhow", "chrono", @@ -7084,8 +7121,6 @@ dependencies = [ "zksync_contracts", "zksync_eth_client", "zksync_protobuf", - "zksync_protobuf_build", - "zksync_protobuf_config", "zksync_system_constants", "zksync_types", "zksync_web3_decl", @@ -7093,7 +7128,7 @@ dependencies = [ [[package]] name = "zkstack_cli_common" -version = "0.1.0" +version = "0.1.2" dependencies = [ "anyhow", "async-trait", @@ -7122,7 +7157,7 @@ dependencies = [ [[package]] name = "zkstack_cli_config" -version = "0.1.0" +version = "0.1.2" dependencies = [ "anyhow", "clap", @@ -7133,6 +7168,7 @@ dependencies = [ "serde_yaml", "strum", "thiserror", + "tokio", "url", "xshell", "zkstack_cli_common", @@ -7140,20 +7176,19 @@ dependencies = [ "zksync_basic_types", "zksync_config", "zksync_protobuf", - "zksync_protobuf_config", "zksync_system_constants", ] [[package]] name = "zkstack_cli_git_version_macro" -version = "0.1.0" +version = "0.1.2" dependencies = [ "chrono", ] [[package]] name = "zkstack_cli_types" -version = "0.1.0" +version = "0.1.2" dependencies = [ "clap", "ethers", @@ -7165,7 +7200,7 @@ dependencies = [ [[package]] name = "zksync_basic_types" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "chrono", @@ -7186,9 +7221,9 @@ dependencies = [ [[package]] name = "zksync_concurrency" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8312ab73d3caa55775bd531795b507fa8f76bd9dabfaeb0954fe43e8fc1323b" +checksum = "cec98400a9e8ba02bfd029eacfe7d6fb7b85b8ef00de59d6bb119d29cc9f7442" dependencies = [ "anyhow", "once_cell", @@ -7205,7 +7240,7 @@ dependencies = [ [[package]] name = "zksync_config" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "rand", @@ -7219,9 +7254,9 @@ dependencies = [ [[package]] name = "zksync_consensus_crypto" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b539960de98df3c3bd27d2d9b97de862027686bbb3bdfc5aaad5b74bb929a1" +checksum = "c04840825dfbe3b9f708d245c87618d5dcf28f29d7b58922971351068a0b8231" dependencies = [ "anyhow", "blst", @@ -7240,9 +7275,9 @@ dependencies = [ [[package]] name = "zksync_consensus_roles" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49949546895a10431b9daec6ec4208ef0917ace006446d304b51f5b234ba462" +checksum = "05498eab1de26869028b5822cfa4490cac625508d427d59668dc73e8162de65f" dependencies = [ "anyhow", "bit-vec", @@ -7262,9 +7297,9 @@ dependencies = [ [[package]] name = "zksync_consensus_utils" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723e2a4b056cc5af192a83163c89a6951ee75c098cc5c4a4cdc435f4232d88bd" +checksum = "f2f9fa69ef68e6a1955a1d7b33077103fb6d106b560fec0d599c6de268f5be03" dependencies = [ "anyhow", "rand", @@ -7274,7 +7309,7 @@ dependencies = [ [[package]] name = "zksync_contracts" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "envy", "hex", @@ -7287,7 +7322,7 @@ dependencies = [ [[package]] name = "zksync_crypto_primitives" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "blake2", @@ -7303,7 +7338,7 @@ dependencies = [ [[package]] name = "zksync_eth_client" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "async-trait", "jsonrpsee", @@ -7320,7 +7355,7 @@ dependencies = [ [[package]] name = "zksync_eth_signer" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "async-trait", "rlp", @@ -7331,7 +7366,7 @@ dependencies = [ [[package]] name = "zksync_mini_merkle_tree" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "once_cell", "zksync_basic_types", @@ -7340,9 +7375,9 @@ dependencies = [ [[package]] name = "zksync_protobuf" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8986ad796f8e00d8999fee72effba1a21bce40f5f877d681ac9cd89a94834d8" +checksum = "d9032e12528c2466293b206d6edb53b7e900e4a4cc4573e4d075ac2dc00e1b55" dependencies = [ "anyhow", "bit-vec", @@ -7361,9 +7396,9 @@ dependencies = [ [[package]] name = "zksync_protobuf_build" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d870b31995e3acb8e47afeb68ebeeffcf6121e70020e65b3d5d31692115d236" +checksum = "7c644fc8ef3c4d343ea42cebd5551e3562933f15dd9b0e68a52c2657603eb0f5" dependencies = [ "anyhow", "heck", @@ -7376,29 +7411,9 @@ dependencies = [ "syn 2.0.89", ] -[[package]] -name = "zksync_protobuf_config" -version = "0.1.0" -dependencies = [ - "anyhow", - "hex", - "prost 0.12.6", - "rand", - "secrecy", - "serde_json", - "serde_yaml", - "tracing", - "zksync_basic_types", - "zksync_concurrency", - "zksync_config", - "zksync_protobuf", - "zksync_protobuf_build", - "zksync_types", -] - [[package]] name = "zksync_system_constants" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "once_cell", "zksync_basic_types", @@ -7406,13 +7421,14 @@ dependencies = [ [[package]] name = "zksync_types" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", "bigdecimal", "blake2", "chrono", + "ciborium", "derive_more", "hex", "itertools 0.10.5", @@ -7438,7 +7454,7 @@ dependencies = [ [[package]] name = "zksync_utils" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "futures", @@ -7453,7 +7469,7 @@ dependencies = [ [[package]] name = "zksync_vlog" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "chrono", @@ -7478,7 +7494,7 @@ dependencies = [ [[package]] name = "zksync_web3_decl" -version = "0.1.0" +version = "26.2.1-non-semver-compat" dependencies = [ "anyhow", "async-trait", diff --git a/zkstack_cli/Cargo.toml b/zkstack_cli/Cargo.toml index f3e0d8a9c9d5..5ef8338dca09 100644 --- a/zkstack_cli/Cargo.toml +++ b/zkstack_cli/Cargo.toml @@ -9,7 +9,7 @@ members = [ resolver = "2" [workspace.package] -version = "0.1.0" +version = "0.1.2" # x-release-please-version edition = "2021" homepage = "https://zksync.io/" license = "MIT OR Apache-2.0" @@ -21,25 +21,24 @@ keywords = ["zk", "cryptography", "blockchain", "ZKStack", "ZKsync"] [workspace.dependencies] # Local dependencies -zkstack_cli_common = { path = "crates/common" } -zkstack_cli_config = { path = "crates/config" } -zkstack_cli_types = { path = "crates/types" } -zkstack_cli_git_version_macro = { path = "crates/git_version_macro" } +zkstack_cli_common = { version = "0.1.2", path = "crates/common" } +zkstack_cli_config = { version = "0.1.2", path = "crates/config" } +zkstack_cli_types = { version = "0.1.2", path = "crates/types" } +zkstack_cli_git_version_macro = { version = "0.1.2", path = "crates/git_version_macro" } # ZkSync deps zksync_config = { path = "../core/lib/config" } -zksync_protobuf_config = { path = "../core/lib/protobuf_config" } zksync_basic_types = { path = "../core/lib/basic_types" } zksync_system_constants = { path = "../core/lib/constants" } zksync_types = { path = "../core/lib/types" } zksync_web3_decl = { path = "../core/lib/web3_decl" } zksync_eth_client = { path = "../core/lib/eth_client" } -zksync_contracts = { path = "../core/lib/contracts" } -zksync_consensus_roles = "=0.7.0" -zksync_consensus_crypto = "=0.7.0" -zksync_consensus_utils = "=0.7.0" -zksync_protobuf = "=0.7.0" -zksync_protobuf_build = "=0.7.0" +zksync_contracts = { path = "../core/lib/contracts" } +zksync_consensus_roles = "=0.8.0" +zksync_consensus_crypto = "=0.8.0" +zksync_consensus_utils = "=0.8.0" +zksync_protobuf = "=0.8.0" +zksync_protobuf_build = "=0.8.0" # External dependencies anyhow = "1.0.82" diff --git a/zkstack_cli/crates/common/src/external_node.rs b/zkstack_cli/crates/common/src/external_node.rs index 8a5cbc3cd14c..7f9031bae4ff 100644 --- a/zkstack_cli/crates/common/src/external_node.rs +++ b/zkstack_cli/crates/common/src/external_node.rs @@ -17,7 +17,7 @@ pub fn run( let cmd = Cmd::new( cmd!( shell, - "cargo run --release --bin zksync_external_node -- + "cargo run --manifest-path ./core/Cargo.toml --release --bin zksync_external_node -- --config-path {config_path} --secrets-path {secrets_path} --external-node-config-path {en_config_path} diff --git a/zkstack_cli/crates/common/src/server.rs b/zkstack_cli/crates/common/src/server.rs index 7f8c2a90e589..0dd93bcd3324 100644 --- a/zkstack_cli/crates/common/src/server.rs +++ b/zkstack_cli/crates/common/src/server.rs @@ -70,7 +70,7 @@ impl Server { let mut cmd = Cmd::new( cmd!( shell, - "cargo run --release --bin zksync_server {uring...} -- + "cargo run --manifest-path ./core/Cargo.toml --release --bin zksync_server {uring...} -- --genesis-path {genesis_path} --wallets-path {wallets_path} --config-path {general_path} @@ -96,7 +96,7 @@ impl Server { /// Builds the server. pub fn build(&self, shell: &Shell) -> anyhow::Result<()> { - let _dir_guard = shell.push_dir(&self.code_path); + let _dir_guard = shell.push_dir(self.code_path.join("core")); Cmd::new(cmd!(shell, "cargo build --release --bin zksync_server")).run()?; Ok(()) } diff --git a/zkstack_cli/crates/config/Cargo.toml b/zkstack_cli/crates/config/Cargo.toml index 0926f2522cb2..c3d4afdce2c8 100644 --- a/zkstack_cli/crates/config/Cargo.toml +++ b/zkstack_cli/crates/config/Cargo.toml @@ -13,7 +13,6 @@ keywords.workspace = true [dependencies] anyhow.workspace = true clap.workspace = true -zkstack_cli_common.workspace = true ethers.workspace = true rand.workspace = true serde.workspace = true @@ -21,12 +20,13 @@ serde_json.workspace = true serde_yaml.workspace = true strum.workspace = true thiserror.workspace = true -zkstack_cli_types.workspace = true +tokio.workspace = true url.workspace = true xshell.workspace = true -zksync_protobuf_config.workspace = true zksync_protobuf.workspace = true zksync_config.workspace = true zksync_basic_types.workspace = true zksync_system_constants.workspace = true +zkstack_cli_common.workspace = true +zkstack_cli_types.workspace = true diff --git a/zkstack_cli/crates/config/src/chain.rs b/zkstack_cli/crates/config/src/chain.rs index 19f275d78f80..b411b1f882a3 100644 --- a/zkstack_cli/crates/config/src/chain.rs +++ b/zkstack_cli/crates/config/src/chain.rs @@ -7,22 +7,20 @@ use serde::{Deserialize, Serialize, Serializer}; use xshell::Shell; use zkstack_cli_types::{BaseToken, L1BatchCommitmentMode, L1Network, ProverMode, WalletCreation}; use zksync_basic_types::L2ChainId; -use zksync_config::{ - configs::{gateway::GatewayChainConfig, GatewayConfig}, - DAClientConfig::{Avail, NoDA}, -}; +use zksync_config::configs::{gateway::GatewayChainConfig, GatewayConfig}; use crate::{ consts::{ - CONFIG_NAME, CONTRACTS_FILE, EN_CONFIG_FILE, GENERAL_FILE, GENESIS_FILE, + CONFIG_NAME, CONTRACTS_FILE, EN_CONFIG_FILE, GATEWAY_FILE, GENERAL_FILE, GENESIS_FILE, L1_CONTRACTS_FOUNDRY, SECRETS_FILE, WALLETS_FILE, }, create_localhost_wallets, + raw::RawConfig, traits::{ FileConfigWithDefaultName, ReadConfig, ReadConfigWithBasePath, SaveConfig, SaveConfigWithBasePath, ZkStackConfig, }, - ContractsConfig, GeneralConfig, GenesisConfig, SecretsConfig, WalletsConfig, GATEWAY_FILE, + ContractsConfig, WalletsConfig, }; /// Chain configuration file. This file is created in the chain @@ -91,12 +89,12 @@ impl ChainConfig { self.shell.get().expect("Not initialized") } - pub fn get_genesis_config(&self) -> anyhow::Result { - GenesisConfig::read_with_base_path(self.get_shell(), &self.configs) + pub async fn get_genesis_config(&self) -> anyhow::Result { + RawConfig::read(self.get_shell(), self.path_to_genesis_config()).await } - pub fn get_general_config(&self) -> anyhow::Result { - GeneralConfig::read_with_base_path(self.get_shell(), &self.configs) + pub async fn get_general_config(&self) -> anyhow::Result { + RawConfig::read(self.get_shell(), self.path_to_general_config()).await } pub fn get_wallets_config(&self) -> anyhow::Result { @@ -112,25 +110,12 @@ impl ChainConfig { anyhow::bail!("Wallets configs has not been found"); } - pub fn get_da_validator_type(&self) -> anyhow::Result { - let general = self.get_general_config().expect("General config not found"); - match ( - self.l1_batch_commit_data_generator_mode, - general.da_client_config, - ) { - (L1BatchCommitmentMode::Rollup, _) => Ok(DAValidatorType::Rollup), - (L1BatchCommitmentMode::Validium, None | Some(NoDA)) => Ok(DAValidatorType::NoDA), - (L1BatchCommitmentMode::Validium, Some(Avail(_))) => Ok(DAValidatorType::Avail), - _ => anyhow::bail!("DAValidatorType is not supported"), - } - } - pub fn get_contracts_config(&self) -> anyhow::Result { ContractsConfig::read_with_base_path(self.get_shell(), &self.configs) } - pub fn get_secrets_config(&self) -> anyhow::Result { - SecretsConfig::read_with_base_path(self.get_shell(), &self.configs) + pub async fn get_secrets_config(&self) -> anyhow::Result { + RawConfig::read(self.get_shell(), self.path_to_secrets_config()).await } pub fn get_gateway_config(&self) -> anyhow::Result { @@ -165,10 +150,6 @@ impl ChainConfig { self.configs.join(GATEWAY_FILE) } - pub fn save_general_config(&self, general_config: &GeneralConfig) -> anyhow::Result<()> { - general_config.save_with_base_path(self.get_shell(), &self.configs) - } - pub fn path_to_l1_foundry(&self) -> PathBuf { self.link_to_code.join(L1_CONTRACTS_FOUNDRY) } diff --git a/zkstack_cli/crates/config/src/consensus_config.rs b/zkstack_cli/crates/config/src/consensus_config.rs deleted file mode 100644 index 0bb4750d1fc0..000000000000 --- a/zkstack_cli/crates/config/src/consensus_config.rs +++ /dev/null @@ -1,18 +0,0 @@ -use zksync_config::configs::consensus::ConsensusConfig; -use zksync_protobuf_config::encode_yaml_repr; - -use crate::{ - traits::{FileConfigWithDefaultName, SaveConfig}, - CONSENSUS_CONFIG_FILE, -}; - -impl FileConfigWithDefaultName for ConsensusConfig { - const FILE_NAME: &'static str = CONSENSUS_CONFIG_FILE; -} - -impl SaveConfig for ConsensusConfig { - fn save(&self, shell: &xshell::Shell, path: impl AsRef) -> anyhow::Result<()> { - let bytes = encode_yaml_repr::(self)?; - Ok(shell.write_file(path.as_ref(), bytes)?) - } -} diff --git a/zkstack_cli/crates/config/src/consensus_secrets.rs b/zkstack_cli/crates/config/src/consensus_secrets.rs deleted file mode 100644 index da551a452799..000000000000 --- a/zkstack_cli/crates/config/src/consensus_secrets.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::path::Path; - -use xshell::Shell; -use zksync_config::configs::consensus::ConsensusSecrets; -use zksync_protobuf_config::read_yaml_repr; - -use crate::traits::ReadConfig; - -impl ReadConfig for ConsensusSecrets { - fn read(shell: &Shell, path: impl AsRef) -> anyhow::Result { - let path = shell.current_dir().join(path); - read_yaml_repr::(&path, false) - } -} diff --git a/zkstack_cli/crates/config/src/da.rs b/zkstack_cli/crates/config/src/da.rs new file mode 100644 index 000000000000..744613c3f8d8 --- /dev/null +++ b/zkstack_cli/crates/config/src/da.rs @@ -0,0 +1,39 @@ +//! Mirrored types for data availability configs. + +use serde::Serialize; + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AvailDefaultConfig { + pub api_node_url: String, + pub app_id: u32, + pub finality_state: Option, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AvailGasRelayConfig { + pub gas_relay_api_url: String, + pub max_retries: usize, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum AvailClientConfig { + FullClient(AvailDefaultConfig), + GasRelay(AvailGasRelayConfig), +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AvailConfig { + pub bridge_api_url: String, + pub timeout_ms: usize, + #[serde(flatten)] + pub config: AvailClientConfig, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct AvailSecrets { + #[serde(skip_serializing_if = "Option::is_none")] + pub seed_phrase: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub gas_relay_api_key: Option, +} diff --git a/zkstack_cli/crates/config/src/external_node.rs b/zkstack_cli/crates/config/src/external_node.rs deleted file mode 100644 index 7d884d3e2346..000000000000 --- a/zkstack_cli/crates/config/src/external_node.rs +++ /dev/null @@ -1,28 +0,0 @@ -use std::path::Path; - -use xshell::Shell; -pub use zksync_config::configs::en_config::ENConfig; -use zksync_protobuf_config::{encode_yaml_repr, read_yaml_repr}; - -use crate::{ - consts::EN_CONFIG_FILE, - traits::{FileConfigWithDefaultName, ReadConfig, SaveConfig}, -}; - -impl FileConfigWithDefaultName for ENConfig { - const FILE_NAME: &'static str = EN_CONFIG_FILE; -} - -impl SaveConfig for ENConfig { - fn save(&self, shell: &Shell, path: impl AsRef) -> anyhow::Result<()> { - let bytes = encode_yaml_repr::(self)?; - Ok(shell.write_file(path, bytes)?) - } -} - -impl ReadConfig for ENConfig { - fn read(shell: &Shell, path: impl AsRef) -> anyhow::Result { - let path = shell.current_dir().join(path); - read_yaml_repr::(&path, false) - } -} diff --git a/zkstack_cli/crates/config/src/forge_interface/deploy_ecosystem/input.rs b/zkstack_cli/crates/config/src/forge_interface/deploy_ecosystem/input.rs index 47fe66143250..c90c3a08de3b 100644 --- a/zkstack_cli/crates/config/src/forge_interface/deploy_ecosystem/input.rs +++ b/zkstack_cli/crates/config/src/forge_interface/deploy_ecosystem/input.rs @@ -7,14 +7,42 @@ use ethers::{ use rand::Rng; use serde::{Deserialize, Serialize}; use zkstack_cli_types::L1Network; -use zksync_basic_types::L2ChainId; +use zksync_basic_types::{protocol_version::ProtocolSemanticVersion, L2ChainId}; use crate::{ consts::INITIAL_DEPLOYMENT_FILE, + raw::RawConfig, traits::{FileConfigWithDefaultName, ZkStackConfig}, - ContractsConfig, GenesisConfig, WalletsConfig, ERC20_DEPLOYMENT_FILE, + ContractsConfig, WalletsConfig, ERC20_DEPLOYMENT_FILE, }; +/// Part of the genesis config influencing `DeployGatewayCTMInput`. +#[derive(Debug)] +pub struct GenesisInput { + pub bootloader_hash: H256, + pub default_aa_hash: H256, + pub evm_emulator_hash: Option, + pub genesis_root_hash: H256, + pub rollup_last_leaf_index: u64, + pub genesis_commitment: H256, + pub protocol_version: ProtocolSemanticVersion, +} + +impl GenesisInput { + // FIXME: is this enough? (cf. aliases in the "real" config definition) + pub fn new(raw: &RawConfig) -> anyhow::Result { + Ok(Self { + bootloader_hash: raw.get("bootloader_hash")?, + default_aa_hash: raw.get("default_aa_hash")?, + evm_emulator_hash: raw.get_opt("evm_emulator_hash")?, + genesis_root_hash: raw.get("genesis_root")?, + rollup_last_leaf_index: raw.get("genesis_rollup_leaf_index")?, + genesis_commitment: raw.get("genesis_batch_commitment")?, + protocol_version: raw.get("genesis_protocol_semantic_version")?, + }) + } +} + #[derive(Debug, Deserialize, Serialize, Clone)] pub struct InitialDeploymentConfig { #[serde(skip_serializing_if = "Option::is_none")] @@ -121,7 +149,7 @@ impl ZkStackConfig for DeployL1Config {} impl DeployL1Config { pub fn new( - genesis_config: &GenesisConfig, + genesis_input: &GenesisInput, wallets_config: &WalletsConfig, initial_deployment_config: &InitialDeploymentConfig, era_chain_id: L2ChainId, @@ -149,18 +177,18 @@ impl DeployL1Config { .diamond_init_max_pubdata_per_batch, diamond_init_minimal_l2_gas_price: initial_deployment_config .diamond_init_minimal_l2_gas_price, - bootloader_hash: genesis_config.bootloader_hash.unwrap(), - default_aa_hash: genesis_config.default_aa_hash.unwrap(), - evm_emulator_hash: genesis_config.evm_emulator_hash, + bootloader_hash: genesis_input.bootloader_hash, + default_aa_hash: genesis_input.default_aa_hash, + evm_emulator_hash: genesis_input.evm_emulator_hash, diamond_init_priority_tx_max_pubdata: initial_deployment_config .diamond_init_priority_tx_max_pubdata, diamond_init_pubdata_pricing_mode: initial_deployment_config .diamond_init_pubdata_pricing_mode, // These values are not optional in genesis config with file based configuration - genesis_batch_commitment: genesis_config.genesis_commitment.unwrap(), - genesis_rollup_leaf_index: genesis_config.rollup_last_leaf_index.unwrap(), - genesis_root: genesis_config.genesis_root_hash.unwrap(), - latest_protocol_version: genesis_config.protocol_version.unwrap().pack(), + genesis_batch_commitment: genesis_input.genesis_commitment, + genesis_rollup_leaf_index: genesis_input.rollup_last_leaf_index, + genesis_root: genesis_input.genesis_root_hash, + latest_protocol_version: genesis_input.protocol_version.pack(), recursion_circuits_set_vks_hash: H256::zero(), recursion_leaf_level_vk_hash: H256::zero(), recursion_node_level_vk_hash: H256::zero(), diff --git a/zkstack_cli/crates/config/src/forge_interface/deploy_gateway_ctm/input.rs b/zkstack_cli/crates/config/src/forge_interface/deploy_gateway_ctm/input.rs index afd71cd97757..fdda2009978c 100644 --- a/zkstack_cli/crates/config/src/forge_interface/deploy_gateway_ctm/input.rs +++ b/zkstack_cli/crates/config/src/forge_interface/deploy_gateway_ctm/input.rs @@ -2,10 +2,10 @@ use ethers::abi::Address; use serde::{Deserialize, Serialize}; use zkstack_cli_types::ProverMode; use zksync_basic_types::{H256, U256}; -use zksync_config::GenesisConfig; use crate::{ - forge_interface::deploy_ecosystem::input::InitialDeploymentConfig, traits::ZkStackConfig, + forge_interface::deploy_ecosystem::input::{GenesisInput, InitialDeploymentConfig}, + traits::ZkStackConfig, ChainConfig, ContractsConfig, EcosystemConfig, }; @@ -59,7 +59,7 @@ impl DeployGatewayCTMInput { pub fn new( chain_config: &ChainConfig, ecosystem_config: &EcosystemConfig, - genesis_config: &GenesisConfig, + genesis_input: &GenesisInput, contracts_config: &ContractsConfig, initial_deployment_config: &InitialDeploymentConfig, ) -> Self { @@ -107,16 +107,16 @@ impl DeployGatewayCTMInput { diamond_init_minimal_l2_gas_price: initial_deployment_config .diamond_init_minimal_l2_gas_price, - bootloader_hash: genesis_config.bootloader_hash.unwrap(), - default_aa_hash: genesis_config.default_aa_hash.unwrap(), + bootloader_hash: genesis_input.bootloader_hash, + default_aa_hash: genesis_input.default_aa_hash, priority_tx_max_gas_limit: initial_deployment_config.priority_tx_max_gas_limit, - genesis_root: genesis_config.genesis_root_hash.unwrap(), - genesis_rollup_leaf_index: genesis_config.rollup_last_leaf_index.unwrap(), - genesis_batch_commitment: genesis_config.genesis_commitment.unwrap(), + genesis_root: genesis_input.genesis_root_hash, + genesis_rollup_leaf_index: genesis_input.rollup_last_leaf_index, + genesis_batch_commitment: genesis_input.genesis_commitment, - latest_protocol_version: genesis_config.protocol_version.unwrap().pack(), + latest_protocol_version: genesis_input.protocol_version.pack(), expected_rollup_l2_da_validator: contracts_config .ecosystem_contracts diff --git a/zkstack_cli/crates/config/src/forge_interface/deploy_l2_contracts/input.rs b/zkstack_cli/crates/config/src/forge_interface/deploy_l2_contracts/input.rs index 78ffcd16eaa8..41aa65bf3bfb 100644 --- a/zkstack_cli/crates/config/src/forge_interface/deploy_l2_contracts/input.rs +++ b/zkstack_cli/crates/config/src/forge_interface/deploy_l2_contracts/input.rs @@ -1,8 +1,10 @@ use ethers::types::Address; use serde::{Deserialize, Serialize}; -use zksync_basic_types::{L2ChainId, U256}; +use zksync_basic_types::{commitment::L1BatchCommitmentMode, L2ChainId, U256}; -use crate::{traits::ZkStackConfig, ChainConfig, ContractsConfig}; +use crate::{ + get_da_client_type, traits::ZkStackConfig, ChainConfig, ContractsConfig, DAValidatorType, +}; impl ZkStackConfig for DeployL2ContractsInput {} @@ -21,13 +23,14 @@ pub struct DeployL2ContractsInput { } impl DeployL2ContractsInput { - pub fn new( + pub async fn new( chain_config: &ChainConfig, contracts_config: &ContractsConfig, era_chain_id: L2ChainId, ) -> anyhow::Result { let contracts = chain_config.get_contracts_config()?; let wallets = chain_config.get_wallets_config()?; + let da_validator_type = get_da_validator_type(chain_config).await?; Ok(Self { era_chain_id, @@ -36,8 +39,22 @@ impl DeployL2ContractsInput { bridgehub: contracts.ecosystem_contracts.bridgehub_proxy_addr, governance: contracts_config.l1.governance_addr, erc20_bridge: contracts.bridges.erc20.l1_address, - da_validator_type: U256::from(chain_config.get_da_validator_type()? as u8), + da_validator_type: U256::from(da_validator_type as u8), consensus_registry_owner: wallets.governor.address, }) } } + +async fn get_da_validator_type(config: &ChainConfig) -> anyhow::Result { + let general = config.get_general_config().await?; + + match ( + config.l1_batch_commit_data_generator_mode, + get_da_client_type(&general), + ) { + (L1BatchCommitmentMode::Rollup, _) => Ok(DAValidatorType::Rollup), + (L1BatchCommitmentMode::Validium, None | Some("no_da")) => Ok(DAValidatorType::NoDA), + (L1BatchCommitmentMode::Validium, Some("avail")) => Ok(DAValidatorType::Avail), + _ => anyhow::bail!("DAValidatorType is not supported"), + } +} diff --git a/zkstack_cli/crates/config/src/forge_interface/gateway_chain_upgrade/input.rs b/zkstack_cli/crates/config/src/forge_interface/gateway_chain_upgrade/input.rs index 41100c55a2ae..8b6320e07ffe 100644 --- a/zkstack_cli/crates/config/src/forge_interface/gateway_chain_upgrade/input.rs +++ b/zkstack_cli/crates/config/src/forge_interface/gateway_chain_upgrade/input.rs @@ -1,3 +1,4 @@ +use anyhow::Context; use ethers::types::Address; use serde::{Deserialize, Serialize}; use zkstack_cli_types::L1BatchCommitmentMode; @@ -23,19 +24,22 @@ pub struct GatewayChainUpgradeChain { } impl GatewayChainUpgradeInput { - pub fn new(current_chain_config: &ChainConfig) -> Self { - let contracts_config = current_chain_config.get_contracts_config().unwrap(); + pub async fn new(current_chain_config: &ChainConfig) -> anyhow::Result { + let contracts_config = current_chain_config + .get_contracts_config() + .context("failed loading contracts config")?; let validum = current_chain_config .get_genesis_config() - .unwrap() - .l1_batch_commit_data_generator_mode + .await + .context("failed loading genesis config")? + .get::("l1_batch_commit_data_generator_mode")? == L1BatchCommitmentMode::Validium; - Self { + Ok(Self { owner_address: current_chain_config .get_wallets_config() - .unwrap() + .context("failed loading wallets config")? .governor .address, chain: GatewayChainUpgradeChain { @@ -45,6 +49,6 @@ impl GatewayChainUpgradeInput { // TODO(EVM-860): we assume that all rollup chains want to forever remain this way permanent_rollup: !validum, }, - } + }) } } diff --git a/zkstack_cli/crates/config/src/forge_interface/gateway_ecosystem_upgrade/input.rs b/zkstack_cli/crates/config/src/forge_interface/gateway_ecosystem_upgrade/input.rs index 8bd300f50581..4d739ac476f5 100644 --- a/zkstack_cli/crates/config/src/forge_interface/gateway_ecosystem_upgrade/input.rs +++ b/zkstack_cli/crates/config/src/forge_interface/gateway_ecosystem_upgrade/input.rs @@ -3,8 +3,9 @@ use serde::{Deserialize, Serialize}; use zksync_basic_types::L2ChainId; use crate::{ - forge_interface::deploy_ecosystem::input::InitialDeploymentConfig, traits::ZkStackConfig, - ContractsConfig, GenesisConfig, + forge_interface::deploy_ecosystem::input::{GenesisInput, InitialDeploymentConfig}, + traits::ZkStackConfig, + ContractsConfig, }; #[derive(Debug, Deserialize, Serialize, Clone)] @@ -21,7 +22,7 @@ impl ZkStackConfig for GatewayEcosystemUpgradeInput {} impl GatewayEcosystemUpgradeInput { pub fn new( - new_genesis_config: &GenesisConfig, + new_genesis_input: &GenesisInput, current_contracts_config: &ContractsConfig, // It is expected to not change between the versions initial_deployment_config: &InitialDeploymentConfig, @@ -48,16 +49,16 @@ impl GatewayEcosystemUpgradeInput { .diamond_init_max_pubdata_per_batch, diamond_init_minimal_l2_gas_price: initial_deployment_config .diamond_init_minimal_l2_gas_price, - bootloader_hash: new_genesis_config.bootloader_hash.unwrap(), - default_aa_hash: new_genesis_config.default_aa_hash.unwrap(), + bootloader_hash: new_genesis_input.bootloader_hash, + default_aa_hash: new_genesis_input.default_aa_hash, diamond_init_priority_tx_max_pubdata: initial_deployment_config .diamond_init_priority_tx_max_pubdata, diamond_init_pubdata_pricing_mode: initial_deployment_config .diamond_init_pubdata_pricing_mode, // These values are not optional in genesis config with file based configuration - genesis_batch_commitment: new_genesis_config.genesis_commitment.unwrap(), - genesis_rollup_leaf_index: new_genesis_config.rollup_last_leaf_index.unwrap(), - genesis_root: new_genesis_config.genesis_root_hash.unwrap(), + genesis_batch_commitment: new_genesis_input.genesis_commitment, + genesis_rollup_leaf_index: new_genesis_input.rollup_last_leaf_index, + genesis_root: new_genesis_input.genesis_root_hash, recursion_circuits_set_vks_hash: H256::zero(), recursion_leaf_level_vk_hash: H256::zero(), recursion_node_level_vk_hash: H256::zero(), diff --git a/zkstack_cli/crates/config/src/general.rs b/zkstack_cli/crates/config/src/general.rs index c1639d6bea15..9eb7dc7756cd 100644 --- a/zkstack_cli/crates/config/src/general.rs +++ b/zkstack_cli/crates/config/src/general.rs @@ -1,16 +1,10 @@ use std::path::{Path, PathBuf}; -use anyhow::Context; -use url::Url; use xshell::Shell; use zkstack_cli_common::yaml::merge_yaml; -use zksync_config::configs::object_store::ObjectStoreMode; -pub use zksync_config::configs::GeneralConfig; -use zksync_protobuf_config::{encode_yaml_repr, read_yaml_repr}; use crate::{ - consts::GENERAL_FILE, - traits::{ConfigWithL2RpcUrl, FileConfigWithDefaultName, ReadConfig, SaveConfig}, + raw::{PatchedConfig, RawConfig}, ChainConfig, }; @@ -40,77 +34,57 @@ impl FileArtifacts { } } -pub fn set_rocks_db_config(config: &mut GeneralConfig, rocks_dbs: RocksDbs) -> anyhow::Result<()> { - config - .db_config - .as_mut() - .context("DB config is not presented")? - .state_keeper_db_path = rocks_dbs.state_keeper.to_str().unwrap().to_string(); - config - .db_config - .as_mut() - .context("DB config is not presented")? - .merkle_tree - .path = rocks_dbs.merkle_tree.to_str().unwrap().to_string(); - config - .protective_reads_writer_config - .as_mut() - .context("Protective reads config is not presented")? - .db_path = rocks_dbs.protective_reads.to_str().unwrap().to_string(); - config - .basic_witness_input_producer_config - .as_mut() - .context("Basic witness input producer config is not presented")? - .db_path = rocks_dbs - .basic_witness_input_producer - .to_str() - .unwrap() - .to_string(); +pub fn set_rocks_db_config(config: &mut PatchedConfig, rocks_dbs: RocksDbs) -> anyhow::Result<()> { + config.insert_path("db.state_keeper_db_path", &rocks_dbs.state_keeper)?; + config.insert_path("db.merkle_tree.path", &rocks_dbs.merkle_tree)?; + config.insert_path( + "protective_reads_writer.db_path", + &rocks_dbs.protective_reads, + )?; + config.insert_path( + "basic_witness_input_producer.db_path", + &rocks_dbs.basic_witness_input_producer, + )?; Ok(()) } -pub fn set_file_artifacts(config: &mut GeneralConfig, file_artifacts: FileArtifacts) { - macro_rules! set_artifact_path { - ($config:expr, $name:ident, $value:expr) => { - $config - .as_mut() - .map(|a| set_artifact_path!(a.$name, $value)) - }; +pub fn set_file_artifacts( + config: &mut PatchedConfig, + file_artifacts: FileArtifacts, +) -> anyhow::Result<()> { + set_file_backed_path_if_selected( + config, + "prover.prover_object_store", + &file_artifacts.prover_object_store, + )?; + set_file_backed_path_if_selected( + config, + "prover.public_object_store", + &file_artifacts.public_object_store, + )?; + set_file_backed_path_if_selected( + config, + "snapshot_creator.object_store", + &file_artifacts.snapshot, + )?; + set_file_backed_path_if_selected( + config, + "snapshot_recovery.object_store", + &file_artifacts.snapshot, + )?; + Ok(()) +} - ($config:expr, $value:expr) => { - $config.as_mut().map(|a| { - if let ObjectStoreMode::FileBacked { - ref mut file_backed_base_path, - } = &mut a.mode - { - *file_backed_base_path = $value.to_str().unwrap().to_string() - } - }) - }; +fn set_file_backed_path_if_selected( + config: &mut PatchedConfig, + prefix: &str, + path: &Path, +) -> anyhow::Result<()> { + let container = config.base().get_raw(&format!("{prefix}.file_backed")); + if matches!(container, Some(serde_yaml::Value::Mapping(_))) { + config.insert_path(&format!("{prefix}.file_backed.file_backed_base_path"), path)?; } - - set_artifact_path!( - config.prover_config, - prover_object_store, - file_artifacts.prover_object_store - ); - set_artifact_path!( - config.prover_config, - public_object_store, - file_artifacts.public_object_store - ); - set_artifact_path!( - config.snapshot_creator, - object_store, - file_artifacts.snapshot - ); - set_artifact_path!( - config.snapshot_recovery, - object_store, - file_artifacts.snapshot - ); - - set_artifact_path!(config.core_object_store, file_artifacts.core_object_store); + Ok(()) } pub fn override_config(shell: &Shell, path: PathBuf, chain: &ChainConfig) -> anyhow::Result<()> { @@ -122,32 +96,13 @@ pub fn override_config(shell: &Shell, path: PathBuf, chain: &ChainConfig) -> any Ok(()) } -impl FileConfigWithDefaultName for GeneralConfig { - const FILE_NAME: &'static str = GENERAL_FILE; -} - -impl SaveConfig for GeneralConfig { - fn save(&self, shell: &Shell, path: impl AsRef) -> anyhow::Result<()> { - let bytes = - encode_yaml_repr::(self)?; - Ok(shell.write_file(path, bytes)?) - } -} - -impl ReadConfig for GeneralConfig { - fn read(shell: &Shell, path: impl AsRef) -> anyhow::Result { - let path = shell.current_dir().join(path); - read_yaml_repr::(&path, false) - } -} - -impl ConfigWithL2RpcUrl for GeneralConfig { - fn get_l2_rpc_url(&self) -> anyhow::Result { - self.api_config - .as_ref() - .map(|api_config| &api_config.web3_json_rpc.http_url) - .context("API config is missing")? - .parse() - .context("Failed to parse L2 RPC URL") - } +pub fn get_da_client_type(general: &RawConfig) -> Option<&str> { + general.get_raw("da_client").and_then(|val| { + let val = val.as_mapping()?; + if val.len() == 1 { + val.keys().next()?.as_str() + } else { + None + } + }) } diff --git a/zkstack_cli/crates/config/src/genesis.rs b/zkstack_cli/crates/config/src/genesis.rs index e457f3d1924c..0f75f374cbf9 100644 --- a/zkstack_cli/crates/config/src/genesis.rs +++ b/zkstack_cli/crates/config/src/genesis.rs @@ -1,41 +1,15 @@ -use std::path::Path; - -use xshell::Shell; -use zksync_basic_types::L1ChainId; -pub use zksync_config::GenesisConfig; -use zksync_protobuf_config::{encode_yaml_repr, read_yaml_repr}; - -use crate::{ - consts::GENESIS_FILE, - traits::{FileConfigWithDefaultName, ReadConfig, SaveConfig}, - ChainConfig, -}; +use crate::{raw::PatchedConfig, ChainConfig}; pub fn update_from_chain_config( - genesis: &mut GenesisConfig, + genesis: &mut PatchedConfig, config: &ChainConfig, ) -> anyhow::Result<()> { - genesis.l2_chain_id = config.chain_id; + genesis.insert("l2_chain_id", config.chain_id.as_u64())?; // TODO(EVM-676): for now, the settlement layer is always the same as the L1 network - genesis.l1_chain_id = L1ChainId(config.l1_network.chain_id()); - genesis.l1_batch_commit_data_generator_mode = config.l1_batch_commit_data_generator_mode; + genesis.insert("l1_chain_id", config.l1_network.chain_id())?; + genesis.insert_yaml( + "l1_batch_commit_data_generator_mode", + config.l1_batch_commit_data_generator_mode, + )?; Ok(()) } - -impl FileConfigWithDefaultName for GenesisConfig { - const FILE_NAME: &'static str = GENESIS_FILE; -} - -impl SaveConfig for GenesisConfig { - fn save(&self, shell: &Shell, path: impl AsRef) -> anyhow::Result<()> { - let bytes = encode_yaml_repr::(self)?; - Ok(shell.write_file(path, bytes)?) - } -} - -impl ReadConfig for GenesisConfig { - fn read(shell: &Shell, path: impl AsRef) -> anyhow::Result { - let path = shell.current_dir().join(path); - read_yaml_repr::(&path, false) - } -} diff --git a/zkstack_cli/crates/config/src/lib.rs b/zkstack_cli/crates/config/src/lib.rs index 4d4fb8da61d2..f4f1e3a68835 100644 --- a/zkstack_cli/crates/config/src/lib.rs +++ b/zkstack_cli/crates/config/src/lib.rs @@ -10,28 +10,25 @@ pub use manipulations::*; pub use secrets::*; pub use wallet_creation::*; pub use wallets::*; -pub use zksync_protobuf_config::{encode_yaml_repr, read_yaml_repr}; mod apps; mod chain; mod consts; mod contracts; +pub mod da; +pub mod docker_compose; mod ecosystem; +pub mod explorer; +pub mod explorer_compose; mod file_config; +pub mod forge_interface; mod gateway; mod general; mod genesis; mod manipulations; +pub mod portal; +pub mod raw; mod secrets; +pub mod traits; mod wallet_creation; mod wallets; - -pub mod consensus_config; -pub mod consensus_secrets; -pub mod docker_compose; -pub mod explorer; -pub mod explorer_compose; -pub mod external_node; -pub mod forge_interface; -pub mod portal; -pub mod traits; diff --git a/zkstack_cli/crates/config/src/raw.rs b/zkstack_cli/crates/config/src/raw.rs new file mode 100644 index 000000000000..b14f404422f8 --- /dev/null +++ b/zkstack_cli/crates/config/src/raw.rs @@ -0,0 +1,156 @@ +use std::path::{Path, PathBuf}; + +use anyhow::Context; +use serde::{de::DeserializeOwned, Serialize}; +use tokio::fs; +use xshell::Shell; + +#[derive(Debug)] +pub struct RawConfig { + path: PathBuf, + inner: serde_yaml::Value, +} + +impl RawConfig { + pub async fn read(shell: &Shell, path: PathBuf) -> anyhow::Result { + let path = shell.current_dir().join(&path); + let raw = fs::read_to_string(&path) + .await + .with_context(|| format!("failed reading config at `{path:?}`"))?; + let inner: serde_yaml::Value = serde_yaml::from_str(&raw) + .with_context(|| format!("failed deserializing config at `{path:?}` as YAML"))?; + anyhow::ensure!( + matches!(&inner, serde_yaml::Value::Mapping(_)), + "configuration is not a map" + ); + Ok(Self { inner, path }) + } + + pub fn get_raw(&self, path: &str) -> Option<&serde_yaml::Value> { + path.split('.') + .try_fold(&self.inner, |ptr, segment| match ptr { + serde_yaml::Value::Mapping(map) => map.get(segment), + _ => None, + }) + } + + pub fn get_opt(&self, path: &str) -> anyhow::Result> { + let Some(raw) = self.get_raw(path) else { + return Ok(None); + }; + serde_yaml::from_value(raw.clone()).with_context(|| { + format!( + "failed deserializing config param `{path}` in `{:?}`", + self.path + ) + }) + } + + pub fn get(&self, path: &str) -> anyhow::Result { + self.get_opt(path)? + .with_context(|| format!("config param `{path}` is missing in {:?}", self.path)) + } + + pub fn patched(self) -> PatchedConfig { + PatchedConfig { base: self } + } +} + +/// Mutable YAML configuration file. +#[derive(Debug)] +#[must_use = "Must be persisted"] +pub struct PatchedConfig { + base: RawConfig, +} + +impl PatchedConfig { + pub fn empty(shell: &Shell, path: PathBuf) -> Self { + let path = shell.current_dir().join(&path); + Self { + base: RawConfig { + path, + inner: serde_yaml::Value::Mapping(serde_yaml::Mapping::default()), + }, + } + } + + pub fn base(&self) -> &RawConfig { + &self.base + } + + pub fn insert(&mut self, key: &str, value: impl Into) -> anyhow::Result<()> { + assert!(!key.is_empty(), "key cannot be empty"); + let value = value.into(); + + let serde_yaml::Value::Mapping(map) = &mut self.base.inner else { + unreachable!(); // checked during initialization + }; + let mut map = map; + if let Some((parent_path, last_segment)) = key.rsplit_once('.') { + for segment in parent_path.split('.') { + if !map.contains_key(segment) { + let new_map = serde_yaml::Mapping::new(); + map.insert(segment.into(), new_map.into()); + } + + map = match map.get_mut(segment) { + Some(serde_yaml::Value::Mapping(child)) => child, + Some(_) => anyhow::bail!("Encountered non-map parent when inserting `{key}`"), + None => unreachable!(), + }; + } + map.insert(last_segment.into(), value); + } else { + map.insert(key.into(), value); + } + Ok(()) + } + + pub fn insert_yaml(&mut self, key: &str, value: impl Serialize) -> anyhow::Result<()> { + let value = serde_yaml::to_value(value) + .unwrap_or_else(|err| panic!("failed serializing config value at `{key}`: {err}")); + self.insert(key, value) + } + + pub fn insert_path(&mut self, key: &str, value: &Path) -> anyhow::Result<()> { + let value = value + .to_str() + .with_context(|| format!("path at `{key}` is not UTF-8"))?; + self.insert(key, value)?; + Ok(()) + } + + pub fn extend(&mut self, source: serde_yaml::Mapping) { + let serde_yaml::Value::Mapping(map) = &mut self.base.inner else { + unreachable!(); // checked during initialization + }; + map.extend(source); + } + + pub fn remove(&mut self, key: &str) { + let serde_yaml::Value::Mapping(map) = &mut self.base.inner else { + unreachable!(); // checked during initialization + }; + let mut map = map; + + if let Some((parent_path, last_segment)) = key.rsplit_once('.') { + for segment in parent_path.split('.') { + map = match map.get_mut(segment) { + Some(serde_yaml::Value::Mapping(child)) => child, + _ => return, + }; + } + map.remove(last_segment); + } else { + map.remove(key); + } + } + + pub async fn save(self) -> anyhow::Result<()> { + let contents = + serde_yaml::to_string(&self.base.inner).context("failed serializing config")?; + fs::write(&self.base.path, contents) + .await + .with_context(|| format!("failed writing config to `{:?}`", self.base.path)) + } +} diff --git a/zkstack_cli/crates/config/src/secrets.rs b/zkstack_cli/crates/config/src/secrets.rs index 91e8964b4651..fd33ebfd86d8 100644 --- a/zkstack_cli/crates/config/src/secrets.rs +++ b/zkstack_cli/crates/config/src/secrets.rs @@ -1,64 +1,27 @@ -use std::{path::Path, str::FromStr}; - -use anyhow::Context; -use xshell::Shell; use zkstack_cli_common::db::DatabaseConfig; -use zksync_basic_types::url::SensitiveUrl; -pub use zksync_config::configs::Secrets as SecretsConfig; -use zksync_protobuf_config::{encode_yaml_repr, read_yaml_repr}; -use crate::{ - consts::SECRETS_FILE, - traits::{FileConfigWithDefaultName, ReadConfig, SaveConfig}, -}; +use crate::raw::PatchedConfig; pub fn set_server_database( - secrets: &mut SecretsConfig, + secrets: &mut PatchedConfig, server_db_config: &DatabaseConfig, ) -> anyhow::Result<()> { - let database = secrets - .database - .as_mut() - .context("Server database must be presented")?; - database.server_url = Some(SensitiveUrl::from(server_db_config.full_url())); - Ok(()) + secrets.insert( + "database.server_url", + server_db_config.full_url().to_string(), + ) } pub fn set_prover_database( - secrets: &mut SecretsConfig, + secrets: &mut PatchedConfig, prover_db_config: &DatabaseConfig, ) -> anyhow::Result<()> { - let database = secrets - .database - .as_mut() - .context("Prover database must be presented")?; - database.prover_url = Some(SensitiveUrl::from(prover_db_config.full_url())); - Ok(()) -} - -pub fn set_l1_rpc_url(secrets: &mut SecretsConfig, l1_rpc_url: String) -> anyhow::Result<()> { - secrets - .l1 - .as_mut() - .context("L1 Secrets must be presented")? - .l1_rpc_url = SensitiveUrl::from_str(&l1_rpc_url)?; - Ok(()) -} - -impl FileConfigWithDefaultName for SecretsConfig { - const FILE_NAME: &'static str = SECRETS_FILE; -} - -impl SaveConfig for SecretsConfig { - fn save(&self, shell: &Shell, path: impl AsRef) -> anyhow::Result<()> { - let bytes = encode_yaml_repr::(self)?; - Ok(shell.write_file(path, bytes)?) - } + secrets.insert( + "database.prover_url", + prover_db_config.full_url().to_string(), + ) } -impl ReadConfig for SecretsConfig { - fn read(shell: &Shell, path: impl AsRef) -> anyhow::Result { - let path = shell.current_dir().join(path); - read_yaml_repr::(&path, false) - } +pub fn set_l1_rpc_url(secrets: &mut PatchedConfig, l1_rpc_url: String) -> anyhow::Result<()> { + secrets.insert("l1.l1_rpc_url", l1_rpc_url) } diff --git a/zkstack_cli/crates/config/src/traits.rs b/zkstack_cli/crates/config/src/traits.rs index d21641e33ff5..e5429cc683c6 100644 --- a/zkstack_cli/crates/config/src/traits.rs +++ b/zkstack_cli/crates/config/src/traits.rs @@ -2,7 +2,6 @@ use std::path::{Path, PathBuf}; use anyhow::{bail, Context}; use serde::{de::DeserializeOwned, Serialize}; -use url::Url; use xshell::Shell; use zkstack_cli_common::files::{ read_json_file, read_toml_file, read_yaml_file, save_json_file, save_toml_file, save_yaml_file, @@ -157,7 +156,3 @@ fn save_with_comment( } Ok(()) } - -pub trait ConfigWithL2RpcUrl { - fn get_l2_rpc_url(&self) -> anyhow::Result; -} diff --git a/zkstack_cli/crates/zkstack/Cargo.toml b/zkstack_cli/crates/zkstack/Cargo.toml index 169fe593ba14..f39b5f5ea085 100644 --- a/zkstack_cli/crates/zkstack/Cargo.toml +++ b/zkstack_cli/crates/zkstack/Cargo.toml @@ -42,7 +42,6 @@ zksync_config.workspace = true zksync_consensus_roles.workspace = true zksync_consensus_crypto.workspace = true zksync_protobuf.workspace = true -zksync_protobuf_config.workspace = true zksync_types.workspace = true zksync_web3_decl.workspace = true zksync_system_constants.workspace = true @@ -61,9 +60,8 @@ clap_complete.workspace = true dirs.workspace = true ethers.workspace = true xshell.workspace = true -zksync_protobuf_build.workspace = true [features] # Features that allows gateway-chain related actions. -# These should be available for outside users until stabilized. +# These should be available for outside users until stabilized. gateway = [] diff --git a/zkstack_cli/crates/zkstack/build.rs b/zkstack_cli/crates/zkstack/build.rs index e52e952bf730..5d077b77fc82 100644 --- a/zkstack_cli/crates/zkstack/build.rs +++ b/zkstack_cli/crates/zkstack/build.rs @@ -25,15 +25,6 @@ fn main() -> anyhow::Result<()> { println!("cargo:error={}", e); }; - zksync_protobuf_build::Config { - input_root: "src/commands/consensus/proto".into(), - proto_root: "zksync/toolbox/consensus".into(), - dependencies: vec!["::zksync_protobuf_config::proto".parse().unwrap()], - protobuf_crate: "::zksync_protobuf".parse().unwrap(), - is_public: false, - } - .generate() - .unwrap(); Ok(()) } @@ -112,15 +103,22 @@ impl ShellAutocomplete for clap_complete::Shell { .context(format!("could not read .{}rc", shell))?; if !shell_rc_content.contains("# zkstack completion") { - std::fs::write( - shell_rc, + let completion_snippet = if shell == "zsh" { + format!( + "{}\n# zkstack completion\nautoload -Uz compinit\ncompinit\nsource \"{}\"\n", + shell_rc_content, + completion_file.to_str().unwrap() + ) + } else { format!( "{}\n# zkstack completion\nsource \"{}\"\n", shell_rc_content, completion_file.to_str().unwrap() - ), - ) - .context(format!("could not write .{}rc", shell))?; + ) + }; + + std::fs::write(shell_rc, completion_snippet) + .context(format!("could not write .{}rc", shell))?; } } else { println!( diff --git a/zkstack_cli/crates/zkstack/completion/_zkstack.zsh b/zkstack_cli/crates/zkstack/completion/_zkstack.zsh index 9c42f83f0020..93496c220e15 100644 --- a/zkstack_cli/crates/zkstack/completion/_zkstack.zsh +++ b/zkstack_cli/crates/zkstack/completion/_zkstack.zsh @@ -1906,9 +1906,7 @@ _arguments "${_arguments_options[@]}" : \ '(--clone)--bellman-cuda-dir=[]:BELLMAN_CUDA_DIR:_default' \ '--bellman-cuda=[]' \ '--setup-compressor-key=[]' \ -'--plonk-path=[]:PLONK_PATH:_default' \ -'--fflonk-path=[]:FFLONK_PATH:_default' \ -'--compressor-type=[]:COMPRESSOR_TYPE:(fflonk plonk all)' \ +'--path=[]:PATH:_files' \ '--region=[]:REGION:(us europe asia)' \ '--mode=[]:MODE:(download generate)' \ '--setup-keys=[]' \ @@ -1979,9 +1977,7 @@ _arguments "${_arguments_options[@]}" : \ ;; (compressor-keys) _arguments "${_arguments_options[@]}" : \ -'--plonk-path=[]:PLONK_PATH:_default' \ -'--fflonk-path=[]:FFLONK_PATH:_default' \ -'--compressor-type=[]:COMPRESSOR_TYPE:(fflonk plonk all)' \ +'--path=[]:PATH:_files' \ '--chain=[Chain to use]:CHAIN:_default' \ '-v[Verbose mode]' \ '--verbose[Verbose mode]' \ diff --git a/zkstack_cli/crates/zkstack/completion/zkstack.fish b/zkstack_cli/crates/zkstack/completion/zkstack.fish index 8ba5afc5a49f..b05971fe5f3f 100644 --- a/zkstack_cli/crates/zkstack/completion/zkstack.fish +++ b/zkstack_cli/crates/zkstack/completion/zkstack.fish @@ -602,11 +602,7 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_ false\t''" complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l setup-compressor-key -r -f -a "true\t'' false\t''" -complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l plonk-path -r -complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l fflonk-path -r -complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l compressor-type -r -f -a "fflonk\t'' -plonk\t'' -all\t''" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l path -r -F complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init" -l region -r -f -a "us\t'' europe\t'' asia\t''" @@ -672,11 +668,7 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_ complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init-bellman-cuda" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init-bellman-cuda" -l ignore-prerequisites -d 'Ignores prerequisites checks' complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from init-bellman-cuda" -s h -l help -d 'Print help' -complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -l plonk-path -r -complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -l fflonk-path -r -complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -l compressor-type -r -f -a "fflonk\t'' -plonk\t'' -all\t''" +complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -l path -r -F complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -l chain -d 'Chain to use' -r complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from compressor-keys" -l ignore-prerequisites -d 'Ignores prerequisites checks' diff --git a/zkstack_cli/crates/zkstack/completion/zkstack.sh b/zkstack_cli/crates/zkstack/completion/zkstack.sh index 280863339c52..a6b4498d53fb 100644 --- a/zkstack_cli/crates/zkstack/completion/zkstack.sh +++ b/zkstack_cli/crates/zkstack/completion/zkstack.sh @@ -7106,24 +7106,16 @@ _zkstack() { return 0 ;; zkstack__prover__compressor__keys) - opts="-v -h --plonk-path --fflonk-path --compressor-type --verbose --chain --ignore-prerequisites --help" + opts="-v -h --path --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi case "${prev}" in - --plonk-path) - COMPREPLY=($(compgen -f "${cur}")) - return 0 - ;; - --fflonk-path) + --path) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --compressor-type) - COMPREPLY=($(compgen -W "fflonk plonk all" -- "${cur}")) - return 0 - ;; --chain) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -7234,7 +7226,7 @@ _zkstack() { return 0 ;; zkstack__prover__init) - opts="-u -d -v -h --dev --proof-store-dir --bucket-base-url --credentials-file --bucket-name --location --project-id --shall-save-to-public-bucket --public-store-dir --public-bucket-base-url --public-credentials-file --public-bucket-name --public-location --public-project-id --clone --bellman-cuda-dir --bellman-cuda --setup-compressor-key --plonk-path --fflonk-path --compressor-type --region --mode --setup-keys --setup-database --prover-db-url --prover-db-name --use-default --dont-drop --cloud-type --verbose --chain --ignore-prerequisites --help" + opts="-u -d -v -h --dev --proof-store-dir --bucket-base-url --credentials-file --bucket-name --location --project-id --shall-save-to-public-bucket --public-store-dir --public-bucket-base-url --public-credentials-file --public-bucket-name --public-location --public-project-id --clone --bellman-cuda-dir --bellman-cuda --setup-compressor-key --path --region --mode --setup-keys --setup-database --prover-db-url --prover-db-name --use-default --dont-drop --cloud-type --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -7304,18 +7296,10 @@ _zkstack() { COMPREPLY=($(compgen -W "true false" -- "${cur}")) return 0 ;; - --plonk-path) - COMPREPLY=($(compgen -f "${cur}")) - return 0 - ;; - --fflonk-path) + --path) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --compressor-type) - COMPREPLY=($(compgen -W "fflonk plonk all" -- "${cur}")) - return 0 - ;; --region) COMPREPLY=($(compgen -W "us europe asia" -- "${cur}")) return 0 diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/accept_chain_ownership.rs b/zkstack_cli/crates/zkstack/src/commands/chain/accept_chain_ownership.rs index 46b92248ae3f..b238c1160f66 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/accept_chain_ownership.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/accept_chain_ownership.rs @@ -7,7 +7,6 @@ use crate::{ accept_ownership::accept_admin, messages::{ MSG_ACCEPTING_ADMIN_SPINNER, MSG_CHAIN_NOT_INITIALIZED, MSG_CHAIN_OWNERSHIP_TRANSFERRED, - MSG_L1_SECRETS_MUST_BE_PRESENTED, }, }; @@ -17,13 +16,8 @@ pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { .load_current_chain() .context(MSG_CHAIN_NOT_INITIALIZED)?; let contracts = chain_config.get_contracts_config()?; - let secrets = chain_config.get_secrets_config()?; - let l1_rpc_url = secrets - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(); + let secrets = chain_config.get_secrets_config().await?; + let l1_rpc_url = secrets.get("l1.l1_rpc_url")?; let spinner = Spinner::new(MSG_ACCEPTING_ADMIN_SPINNER); accept_admin( @@ -33,7 +27,7 @@ pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { &chain_config.get_wallets_config()?.governor, contracts.l1.diamond_proxy_addr, &args, - l1_rpc_url.clone(), + l1_rpc_url, ) .await?; spinner.finish(); diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/args/genesis.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/genesis.rs index ef98a777352e..08421fcc6abf 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/args/genesis.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/args/genesis.rs @@ -56,18 +56,16 @@ impl GenesisArgs { } } - pub fn fill_values_with_secrets( + pub async fn fill_values_with_secrets( mut self, chain_config: &ChainConfig, ) -> anyhow::Result { - let secrets = chain_config.get_secrets_config()?; - let database = secrets - .database - .context("Database secrets must be present")?; + let secrets = chain_config.get_secrets_config().await?; + let server_url = secrets.get_opt::("database.server_url")?; - let (server_db_url, server_db_name) = if let Some(db_full_url) = database.server_url { - let db_config = DatabaseConfig::from_url(db_full_url.expose_url()) - .context("Invalid server database URL")?; + let (server_db_url, server_db_name) = if let Some(db_full_url) = &server_url { + let db_config = + DatabaseConfig::from_url(db_full_url).context("Invalid server database URL")?; (Some(db_config.url), Some(db_config.name)) } else { (None, None) diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/args/init/da_configs.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/init/da_configs.rs index 4d0e97e7ef05..7a8e6d5f838e 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/args/init/da_configs.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/args/init/da_configs.rs @@ -3,11 +3,8 @@ use serde::{Deserialize, Serialize}; use strum::{Display, EnumIter, IntoEnumIterator}; use url::Url; use zkstack_cli_common::{Prompt, PromptSelect}; -use zksync_config::{ - configs::da_client::avail::{ - AvailClientConfig, AvailDefaultConfig, AvailGasRelayConfig, AvailSecrets, - }, - AvailConfig, +use zkstack_cli_config::da::{ + AvailClientConfig, AvailConfig, AvailDefaultConfig, AvailGasRelayConfig, AvailSecrets, }; use crate::{ diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/build_transactions.rs b/zkstack_cli/crates/zkstack/src/commands/chain/build_transactions.rs index 3bf4db7188f7..43ea4b55ab37 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/build_transactions.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/build_transactions.rs @@ -40,8 +40,9 @@ pub(crate) async fn run(args: BuildTransactionsArgs, shell: &Shell) -> anyhow::R logger::note(MSG_SELECTED_CONFIG, logger::object_to_string(&chain_config)); - let mut genesis_config = chain_config.get_genesis_config()?; + let mut genesis_config = chain_config.get_genesis_config().await?.patched(); update_from_chain_config(&mut genesis_config, &chain_config)?; + // FIXME: config isn't saved; why? // Copy ecosystem contracts let mut contracts_config = config diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/convert_to_gateway.rs b/zkstack_cli/crates/zkstack/src/commands/chain/convert_to_gateway.rs index 0b06cd8de3c2..cb4c5c8e555d 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/convert_to_gateway.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/convert_to_gateway.rs @@ -9,19 +9,19 @@ use zkstack_cli_common::{ }; use zkstack_cli_config::{ forge_interface::{ - deploy_ecosystem::input::InitialDeploymentConfig, + deploy_ecosystem::input::{GenesisInput, InitialDeploymentConfig}, deploy_gateway_ctm::{input::DeployGatewayCTMInput, output::DeployGatewayCTMOutput}, gateway_preparation::{input::GatewayPreparationConfig, output::GatewayPreparationOutput}, script_params::{DEPLOY_GATEWAY_CTM, GATEWAY_GOVERNANCE_TX_PATH1, GATEWAY_PREPARATION}, }, traits::{ReadConfig, SaveConfig, SaveConfigWithBasePath}, - ChainConfig, EcosystemConfig, GenesisConfig, + ChainConfig, EcosystemConfig, }; use zksync_basic_types::H256; use zksync_config::configs::GatewayConfig; use crate::{ - messages::{MSG_CHAIN_NOT_INITIALIZED, MSG_L1_SECRETS_MUST_BE_PRESENTED}, + messages::MSG_CHAIN_NOT_INITIALIZED, utils::forge::{check_the_balance, fill_forge_private_key, WalletOwner}, }; @@ -55,14 +55,12 @@ pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { .load_chain(chain_name) .context(MSG_CHAIN_NOT_INITIALIZED)?; let l1_url = chain_config - .get_secrets_config()? - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(); + .get_secrets_config() + .await? + .get::("l1.l1_rpc_url")?; let mut chain_contracts_config = chain_config.get_contracts_config()?; - let chain_genesis_config = chain_config.get_genesis_config()?; + let chain_genesis_config = chain_config.get_genesis_config().await?; + let genesis_input = GenesisInput::new(&chain_genesis_config)?; // Firstly, deploying gateway contracts let gateway_config = calculate_gateway_ctm( @@ -70,7 +68,7 @@ pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { args.clone(), &ecosystem_config, &chain_config, - &chain_genesis_config, + &genesis_input, &ecosystem_config.get_initial_deployment_config().unwrap(), l1_url.clone(), ) @@ -147,7 +145,7 @@ pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { args, &ecosystem_config, &chain_config, - &chain_genesis_config, + &genesis_input, &ecosystem_config.get_initial_deployment_config().unwrap(), l1_url, ) @@ -163,8 +161,8 @@ pub async fn calculate_gateway_ctm( forge_args: ForgeScriptArgs, config: &EcosystemConfig, chain_config: &ChainConfig, - chain_genesis_config: &GenesisConfig, - initial_deployemnt_config: &InitialDeploymentConfig, + genesis_input: &GenesisInput, + initial_deployment_config: &InitialDeploymentConfig, l1_rpc_url: String, ) -> anyhow::Result { let contracts_config = chain_config.get_contracts_config()?; @@ -173,9 +171,9 @@ pub async fn calculate_gateway_ctm( let deploy_config = DeployGatewayCTMInput::new( chain_config, config, - chain_genesis_config, + genesis_input, &contracts_config, - initial_deployemnt_config, + initial_deployment_config, ); deploy_config.save(shell, deploy_config_path)?; @@ -214,20 +212,19 @@ pub async fn deploy_gateway_ctm( forge_args: ForgeScriptArgs, config: &EcosystemConfig, chain_config: &ChainConfig, - chain_genesis_config: &GenesisConfig, - initial_deployemnt_config: &InitialDeploymentConfig, + genesis_input: &GenesisInput, + initial_deployment_config: &InitialDeploymentConfig, l1_rpc_url: String, ) -> anyhow::Result<()> { let contracts_config = chain_config.get_contracts_config()?; - // let contracts_config = config.get_contracts_config()?; let deploy_config_path = DEPLOY_GATEWAY_CTM.input(&config.link_to_code); let deploy_config = DeployGatewayCTMInput::new( chain_config, config, - chain_genesis_config, + genesis_input, &contracts_config, - initial_deployemnt_config, + initial_deployment_config, ); deploy_config.save(shell, deploy_config_path)?; diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/create.rs b/zkstack_cli/crates/zkstack/src/commands/chain/create.rs index 529d861a2559..1112907374a4 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/create.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/create.rs @@ -4,11 +4,11 @@ use anyhow::Context; use xshell::Shell; use zkstack_cli_common::{logger, spinner::Spinner}; use zkstack_cli_config::{ - create_local_configs_dir, create_wallets, - traits::{ReadConfigWithBasePath, SaveConfigWithBasePath}, - ChainConfig, EcosystemConfig, GenesisConfig, + create_local_configs_dir, create_wallets, raw::RawConfig, traits::SaveConfigWithBasePath, + ChainConfig, EcosystemConfig, GENESIS_FILE, }; use zksync_basic_types::L2ChainId; +use zksync_types::H256; use crate::{ commands::chain::args::create::{ChainCreateArgs, ChainCreateArgsFinal}, @@ -20,12 +20,12 @@ use crate::{ utils::link_to_code::resolve_link_to_code, }; -pub fn run(args: ChainCreateArgs, shell: &Shell) -> anyhow::Result<()> { +pub async fn run(args: ChainCreateArgs, shell: &Shell) -> anyhow::Result<()> { let mut ecosystem_config = EcosystemConfig::from_file(shell)?; - create(args, &mut ecosystem_config, shell) + create(args, &mut ecosystem_config, shell).await } -pub fn create( +pub async fn create( args: ChainCreateArgs, ecosystem_config: &mut EcosystemConfig, shell: &Shell, @@ -46,7 +46,7 @@ pub fn create( let spinner = Spinner::new(MSG_CREATING_CHAIN_CONFIGURATIONS_SPINNER); let name = args.chain_name.clone(); let set_as_default = args.set_as_default; - create_chain_inner(args, ecosystem_config, shell)?; + create_chain_inner(args, ecosystem_config, shell).await?; if set_as_default { ecosystem_config.default_chain = name; ecosystem_config.save_with_base_path(shell, ".")?; @@ -58,7 +58,7 @@ pub fn create( Ok(()) } -pub(crate) fn create_chain_inner( +pub(crate) async fn create_chain_inner( args: ChainCreateArgsFinal, ecosystem_config: &EcosystemConfig, shell: &Shell, @@ -82,11 +82,12 @@ pub(crate) fn create_chain_inner( args.link_to_code.clone(), args.update_submodules, )?; - let default_genesis_config = GenesisConfig::read_with_base_path( - shell, - EcosystemConfig::default_configs_path(&link_to_code), - )?; - let has_evm_emulation_support = default_genesis_config.evm_emulator_hash.is_some(); + let genesis_config_path = + EcosystemConfig::default_configs_path(&link_to_code).join(GENESIS_FILE); + let default_genesis_config = RawConfig::read(shell, genesis_config_path).await?; + let has_evm_emulation_support = default_genesis_config + .get_opt::("evm_emulator_hash")? + .is_some(); if args.evm_emulator && !has_evm_emulation_support { anyhow::bail!(MSG_EVM_EMULATOR_HASH_MISSING_ERR); } diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/deploy_l2_contracts.rs b/zkstack_cli/crates/zkstack/src/commands/chain/deploy_l2_contracts.rs index 7cf628b1170b..98130859b7a3 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/deploy_l2_contracts.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/deploy_l2_contracts.rs @@ -23,10 +23,7 @@ use zkstack_cli_config::{ }; use crate::{ - messages::{ - MSG_CHAIN_NOT_INITIALIZED, MSG_DEPLOYING_L2_CONTRACT_SPINNER, - MSG_L1_SECRETS_MUST_BE_PRESENTED, - }, + messages::{MSG_CHAIN_NOT_INITIALIZED, MSG_DEPLOYING_L2_CONTRACT_SPINNER}, utils::forge::{check_the_balance, fill_forge_private_key, WalletOwner}, }; @@ -263,9 +260,11 @@ async fn call_forge( chain_config, &ecosystem_config.get_contracts_config()?, ecosystem_config.era_chain_id, - )?; + ) + .await?; + let foundry_contracts_path = chain_config.path_to_l1_foundry(); - let secrets = chain_config.get_secrets_config()?; + let secrets = chain_config.get_secrets_config().await?; input.save( shell, DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.input(&chain_config.link_to_code), @@ -277,14 +276,7 @@ async fn call_forge( forge_args.clone(), ) .with_ffi() - .with_rpc_url( - secrets - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(), - ); + .with_rpc_url(secrets.get("l1.l1_rpc_url")?); if with_broadcast { forge = forge.with_broadcast(); } diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/deploy_paymaster.rs b/zkstack_cli/crates/zkstack/src/commands/chain/deploy_paymaster.rs index 1c103ea29910..126b0df1d3e5 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/deploy_paymaster.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/deploy_paymaster.rs @@ -11,7 +11,7 @@ use zkstack_cli_config::{ }; use crate::{ - messages::{MSG_CHAIN_NOT_INITIALIZED, MSG_L1_SECRETS_MUST_BE_PRESENTED}, + messages::MSG_CHAIN_NOT_INITIALIZED, utils::forge::{check_the_balance, fill_forge_private_key, WalletOwner}, }; @@ -39,19 +39,12 @@ pub async fn deploy_paymaster( shell, DEPLOY_PAYMASTER_SCRIPT_PARAMS.input(&chain_config.link_to_code), )?; - let secrets = chain_config.get_secrets_config()?; + let secrets = chain_config.get_secrets_config().await?; let mut forge = Forge::new(&foundry_contracts_path) .script(&DEPLOY_PAYMASTER_SCRIPT_PARAMS.script(), forge_args.clone()) .with_ffi() - .with_rpc_url( - secrets - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(), - ); + .with_rpc_url(secrets.get("l1.l1_rpc_url")?); if let Some(address) = sender { forge = forge.with_sender(address); diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/enable_evm_emulator.rs b/zkstack_cli/crates/zkstack/src/commands/chain/enable_evm_emulator.rs index e15cdbacf103..2e80fb8ab7b7 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/enable_evm_emulator.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/enable_evm_emulator.rs @@ -1,13 +1,13 @@ use anyhow::Context; use xshell::Shell; use zkstack_cli_common::{forge::ForgeScriptArgs, logger}; -use zkstack_cli_config::{traits::ReadConfigWithBasePath, EcosystemConfig, GenesisConfig}; +use zkstack_cli_config::{raw::RawConfig, EcosystemConfig, GENESIS_FILE}; +use zksync_types::H256; use crate::{ enable_evm_emulator::enable_evm_emulator, messages::{ MSG_CHAIN_NOT_INITIALIZED, MSG_EVM_EMULATOR_ENABLED, MSG_EVM_EMULATOR_HASH_MISSING_ERR, - MSG_L1_SECRETS_MUST_BE_PRESENTED, }, }; @@ -17,22 +17,18 @@ pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { .load_current_chain() .context(MSG_CHAIN_NOT_INITIALIZED)?; - let default_genesis_config = GenesisConfig::read_with_base_path( - shell, - EcosystemConfig::default_configs_path(&chain_config.link_to_code), - )?; + let genesis_config_path = + EcosystemConfig::default_configs_path(&chain_config.link_to_code).join(GENESIS_FILE); + let default_genesis_config = RawConfig::read(shell, genesis_config_path).await?; - let has_evm_emulation_support = default_genesis_config.evm_emulator_hash.is_some(); + let has_evm_emulation_support = default_genesis_config + .get_opt::("evm_emulator_hash")? + .is_some(); anyhow::ensure!(has_evm_emulation_support, MSG_EVM_EMULATOR_HASH_MISSING_ERR); let contracts = chain_config.get_contracts_config()?; - let secrets = chain_config.get_secrets_config()?; - let l1_rpc_url = secrets - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(); + let secrets = chain_config.get_secrets_config().await?; + let l1_rpc_url = secrets.get("l1.l1_rpc_url")?; enable_evm_emulator( shell, diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/gateway_upgrade.rs b/zkstack_cli/crates/zkstack/src/commands/chain/gateway_upgrade.rs index f096daef032a..f61f0926369c 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/gateway_upgrade.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/gateway_upgrade.rs @@ -25,15 +25,14 @@ use zkstack_cli_config::{ ChainConfig, EcosystemConfig, }; use zkstack_cli_types::L1BatchCommitmentMode; -use zksync_basic_types::U256; -use zksync_types::Address; +use zksync_basic_types::{Address, U256}; use crate::{ commands::dev::commands::gateway::{ check_chain_readiness, fetch_chain_info, get_admin_call_builder, set_upgrade_timestamp_calldata, DAMode, GatewayUpgradeArgsInner, GatewayUpgradeInfo, }, - messages::{MSG_CHAIN_NOT_INITIALIZED, MSG_L1_SECRETS_MUST_BE_PRESENTED}, + messages::MSG_CHAIN_NOT_INITIALIZED, utils::forge::{fill_forge_private_key, WalletOwner}, }; @@ -97,12 +96,9 @@ pub async fn run(args: GatewayUpgradeArgs, shell: &Shell) -> anyhow::Result<()> .context(MSG_CHAIN_NOT_INITIALIZED)?; let l1_url = chain_config - .get_secrets_config()? - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(); + .get_secrets_config() + .await? + .get("l1.l1_rpc_url")?; match args.chain_upgrade_stage { GatewayChainUpgradeStage::PrepareStage1 => { @@ -138,31 +134,27 @@ async fn prepare_stage1( // No need to save it, we have enough for now let mut contracts_config = chain_config.get_contracts_config()?; - let general_config = chain_config.get_general_config()?; - let genesis_config = chain_config.get_genesis_config()?; + let general_config = chain_config.get_general_config().await?; + let genesis_config = chain_config.get_genesis_config().await?; let upgrade_info = GatewayUpgradeInfo::from_gateway_ecosystem_upgrade( contracts_config.ecosystem_contracts.bridgehub_proxy_addr, gateway_ecosystem_preparation_output, ); - let da_mode: DAMode = - if genesis_config.l1_batch_commit_data_generator_mode == L1BatchCommitmentMode::Rollup { - DAMode::PermanentRollup - } else { - DAMode::Validium - }; + let commitment_mode = + genesis_config.get::("l1_batch_commit_data_generator_mode")?; + let da_mode = match commitment_mode { + L1BatchCommitmentMode::Rollup => DAMode::PermanentRollup, + L1BatchCommitmentMode::Validium => DAMode::Validium, + }; let chain_info = fetch_chain_info( &upgrade_info, &GatewayUpgradeArgsInner { chain_id: chain_config.chain_id.as_u64(), l1_rpc_url: l1_url, - l2_rpc_url: general_config - .api_config - .context("api config")? - .web3_json_rpc - .http_url, + l2_rpc_url: general_config.get("api.web3_json_rpc.http_url")?, validator_addr1: chain_config.get_wallets_config()?.operator.address, validator_addr2: chain_config.get_wallets_config()?.blob_operator.address, da_mode, @@ -265,19 +257,13 @@ async fn finalize_stage1( println!("Finalizing stage1 of chain upgrade!"); let contracts_config = chain_config.get_contracts_config()?; - let general_config = chain_config.get_general_config()?; - let genesis_config = chain_config.get_genesis_config()?; + let general_config = chain_config.get_general_config().await?; + let genesis_config = chain_config.get_genesis_config().await?; println!("Checking chain readiness..."); check_chain_readiness( l1_url.clone(), - general_config - .api_config - .as_ref() - .context("api")? - .web3_json_rpc - .http_url - .clone(), + general_config.get("api.web3_json_rpc.http_url")?, chain_config.chain_id.as_u64(), ) .await?; @@ -287,12 +273,12 @@ async fn finalize_stage1( let gateway_ecosystem_preparation_output = GatewayEcosystemUpgradeOutput::read_with_base_path(shell, &ecosystem_config.config)?; - let da_mode: DAMode = - if genesis_config.l1_batch_commit_data_generator_mode == L1BatchCommitmentMode::Rollup { - DAMode::PermanentRollup - } else { - DAMode::Validium - }; + let commitment_mode = + genesis_config.get::("l1_batch_commit_data_generator_mode")?; + let da_mode = match commitment_mode { + L1BatchCommitmentMode::Rollup => DAMode::PermanentRollup, + L1BatchCommitmentMode::Validium => DAMode::Validium, + }; let upgrade_info = GatewayUpgradeInfo::from_gateway_ecosystem_upgrade( contracts_config.ecosystem_contracts.bridgehub_proxy_addr, @@ -301,11 +287,7 @@ async fn finalize_stage1( let args = GatewayUpgradeArgsInner { chain_id: chain_config.chain_id.as_u64(), l1_rpc_url: l1_url.clone(), - l2_rpc_url: general_config - .api_config - .context("api config")? - .web3_json_rpc - .http_url, + l2_rpc_url: general_config.get("api.web3_json_rpc.http_url")?, validator_addr1: chain_config.get_wallets_config()?.operator.address, validator_addr2: chain_config.get_wallets_config()?.blob_operator.address, da_mode, @@ -313,15 +295,10 @@ async fn finalize_stage1( }; let chain_info = fetch_chain_info(&upgrade_info, &args).await?; - let admin_calls_finalize = get_admin_call_builder(&upgrade_info, &chain_info, args); - admin_calls_finalize.display(); - let admin_calldata = admin_calls_finalize.compile_full_calldata(); - call_chain_admin(l1_url, chain_config, admin_calldata).await?; - println!("done!"); Ok(()) diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/database.rs b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/database.rs index fe12bc017a45..cda28883d0f3 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/database.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/database.rs @@ -8,8 +8,8 @@ use zkstack_cli_common::{ logger, }; use zkstack_cli_config::{ - override_config, set_file_artifacts, set_rocks_db_config, set_server_database, - traits::SaveConfigWithBasePath, ChainConfig, EcosystemConfig, FileArtifacts, + override_config, set_file_artifacts, set_rocks_db_config, set_server_database, ChainConfig, + EcosystemConfig, FileArtifacts, }; use zkstack_cli_types::ProverMode; use zksync_basic_types::commitment::L1BatchCommitmentMode; @@ -34,10 +34,10 @@ pub async fn run(args: GenesisArgs, shell: &Shell) -> anyhow::Result<()> { .load_current_chain() .context(MSG_CHAIN_NOT_INITIALIZED)?; - let mut secrets = chain_config.get_secrets_config()?; - let args = args.fill_values_with_secrets(&chain_config)?; + let mut secrets = chain_config.get_secrets_config().await?.patched(); + let args = args.fill_values_with_secrets(&chain_config).await?; set_server_database(&mut secrets, &args.server_db)?; - secrets.save_with_base_path(shell, &chain_config.configs)?; + secrets.save().await?; initialize_server_database( shell, @@ -78,7 +78,7 @@ pub async fn initialize_server_database( Ok(()) } -pub fn update_configs( +pub async fn update_configs( args: GenesisArgsFinal, shell: &Shell, config: &ChainConfig, @@ -86,18 +86,18 @@ pub fn update_configs( shell.create_dir(&config.rocks_db_path)?; // Update secrets configs - let mut secrets = config.get_secrets_config()?; + let mut secrets = config.get_secrets_config().await?.patched(); set_server_database(&mut secrets, &args.server_db)?; - secrets.save_with_base_path(shell, &config.configs)?; + secrets.save().await?; // Update general config - let mut general = config.get_general_config()?; + let mut general = config.get_general_config().await?.patched(); let rocks_db = recreate_rocksdb_dirs(shell, &config.rocks_db_path, RocksDBDirOption::Main) .context(MSG_RECREATE_ROCKS_DB_ERRROR)?; let file_artifacts = FileArtifacts::new(config.artifacts.clone()); set_rocks_db_config(&mut general, rocks_db)?; - set_file_artifacts(&mut general, file_artifacts); - general.save_with_base_path(shell, &config.configs)?; + set_file_artifacts(&mut general, file_artifacts)?; + general.save().await?; let link_to_code = config.link_to_code.clone(); if config.prover_version != ProverMode::NoProofs { diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/mod.rs index 5cb289d32609..ee4bd90b3e15 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/mod.rs @@ -7,7 +7,7 @@ use zkstack_cli_config::{ChainConfig, EcosystemConfig}; use crate::{ commands::chain::{ args::genesis::{GenesisArgs, GenesisArgsFinal}, - genesis::{self, database::initialize_server_database, server::run_server_genesis}, + genesis::{database::initialize_server_database, server::run_server_genesis}, }, messages::{ MSG_CHAIN_NOT_INITIALIZED, MSG_GENESIS_COMPLETED, MSG_INITIALIZING_DATABASES_SPINNER, @@ -63,7 +63,7 @@ pub async fn genesis( shell: &Shell, config: &ChainConfig, ) -> anyhow::Result<()> { - genesis::database::update_configs(args.clone(), shell, config)?; + database::update_configs(args.clone(), shell, config).await?; logger::note( MSG_SELECTED_CONFIG, diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/server.rs b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/server.rs index 9a52595c978c..9e61d8f402e4 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/server.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/server.rs @@ -7,7 +7,7 @@ use zkstack_cli_common::{ }; use zkstack_cli_config::{ traits::FileConfigWithDefaultName, ChainConfig, ContractsConfig, EcosystemConfig, - GeneralConfig, GenesisConfig, SecretsConfig, WalletsConfig, + WalletsConfig, GENERAL_FILE, GENESIS_FILE, SECRETS_FILE, }; use crate::messages::{ @@ -35,10 +35,10 @@ pub fn run_server_genesis(chain_config: &ChainConfig, shell: &Shell) -> anyhow:: .run( shell, ServerMode::Genesis, - GenesisConfig::get_path_with_base_path(&chain_config.configs), + chain_config.configs.join(GENESIS_FILE), WalletsConfig::get_path_with_base_path(&chain_config.configs), - GeneralConfig::get_path_with_base_path(&chain_config.configs), - SecretsConfig::get_path_with_base_path(&chain_config.configs), + chain_config.configs.join(GENERAL_FILE), + chain_config.configs.join(SECRETS_FILE), ContractsConfig::get_path_with_base_path(&chain_config.configs), None, vec![], diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/init/configs.rs b/zkstack_cli/crates/zkstack/src/commands/chain/init/configs.rs index 4db4c9927de1..dafc786333da 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/init/configs.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/init/configs.rs @@ -1,12 +1,11 @@ use anyhow::Context; -use ethers::types::Address; use xshell::Shell; use zkstack_cli_common::logger; use zkstack_cli_config::{ copy_configs, set_l1_rpc_url, traits::SaveConfigWithBasePath, update_from_chain_config, ChainConfig, ContractsConfig, EcosystemConfig, }; -use zksync_config::configs::DataAvailabilitySecrets; +use zksync_types::Address; use crate::{ commands::{ @@ -21,11 +20,11 @@ use crate::{ portal::update_portal_config, }, messages::{ - MSG_CHAIN_CONFIGS_INITIALIZED, MSG_CHAIN_NOT_FOUND_ERR, MSG_CONSENSUS_CONFIG_MISSING_ERR, + MSG_CHAIN_CONFIGS_INITIALIZED, MSG_CHAIN_NOT_FOUND_ERR, MSG_PORTAL_FAILED_TO_CREATE_CONFIG_ERR, }, utils::{ - consensus::{generate_consensus_keys, get_consensus_secrets, get_genesis_specs}, + consensus::{generate_consensus_keys, set_consensus_secrets, set_genesis_specs}, ports::EcosystemPortsScanner, }, }; @@ -61,52 +60,31 @@ pub async fn init_configs( )?; } - let consensus_keys = generate_consensus_keys(); - - // Initialize secrets config - let mut secrets = chain_config.get_secrets_config()?; - set_l1_rpc_url(&mut secrets, init_args.l1_rpc_url.clone())?; - secrets.consensus = Some(get_consensus_secrets(&consensus_keys)); - - let mut general_config = chain_config.get_general_config()?; - - if general_config.proof_data_handler_config.is_some() && general_config.prover_gateway.is_some() - { - let proof_data_handler_config = general_config.proof_data_handler_config.clone().unwrap(); - let mut prover_gateway = general_config.prover_gateway.clone().unwrap(); - - prover_gateway.api_url = - format!("http://127.0.0.1:{}", proof_data_handler_config.http_port); - - general_config.prover_gateway = Some(prover_gateway); + let mut general_config = chain_config.get_general_config().await?.patched(); + let prover_data_handler_port = general_config + .base() + .get_opt::("data_handler.http_port")?; + if let Some(port) = prover_data_handler_port { + general_config.insert("prover_gateway.api_url", format!("http://127.0.0.1:{port}"))?; } - let mut consensus_config = general_config - .consensus_config - .context(MSG_CONSENSUS_CONFIG_MISSING_ERR)?; - - consensus_config.genesis_spec = Some(get_genesis_specs(chain_config, &consensus_keys)); + let consensus_keys = generate_consensus_keys(); + set_genesis_specs(&mut general_config, chain_config, &consensus_keys)?; - general_config.consensus_config = Some(consensus_config); - if let Some(validium_config) = init_args.validium_config.clone() { - match validium_config { - ValidiumType::NoDA => { - general_config.da_client_config = None; - } - ValidiumType::Avail((avail_config, avail_secrets)) => { - general_config.da_client_config = Some(avail_config.into()); - secrets.data_availability = Some(DataAvailabilitySecrets::Avail(avail_secrets)); - } + match &init_args.validium_config { + None | Some(ValidiumType::NoDA) => { + general_config.remove("da_client"); + } + Some(ValidiumType::Avail((avail_config, _))) => { + general_config.insert_yaml("da_client.avail", avail_config)?; } } - - secrets.save_with_base_path(shell, &chain_config.configs)?; - general_config.save_with_base_path(shell, &chain_config.configs)?; + general_config.save().await?; // Initialize genesis config - let mut genesis_config = chain_config.get_genesis_config()?; + let mut genesis_config = chain_config.get_genesis_config().await?.patched(); update_from_chain_config(&mut genesis_config, chain_config)?; - genesis_config.save_with_base_path(shell, &chain_config.configs)?; + genesis_config.save().await?; // Initialize contracts config let mut contracts_config = ecosystem_config.get_contracts_config()?; @@ -115,12 +93,24 @@ pub async fn init_configs( contracts_config.l1.chain_admin_addr = Address::zero(); contracts_config.l1.base_token_addr = chain_config.base_token.address; contracts_config.l1.base_token_asset_id = Some(encode_ntv_asset_id( - genesis_config.l1_chain_id.0.into(), + chain_config.l1_network.chain_id().into(), contracts_config.l1.base_token_addr, )); contracts_config.save_with_base_path(shell, &chain_config.configs)?; - genesis::database::update_configs(init_args.genesis_args.clone(), shell, chain_config)?; + // Initialize secrets config + let mut secrets = chain_config.get_secrets_config().await?.patched(); + set_l1_rpc_url(&mut secrets, init_args.l1_rpc_url.clone())?; + set_consensus_secrets(&mut secrets, &consensus_keys)?; + match &init_args.validium_config { + None | Some(ValidiumType::NoDA) => { /* Do nothing */ } + Some(ValidiumType::Avail((_, avail_secrets))) => { + secrets.insert_yaml("da.avail", avail_secrets)?; + } + } + secrets.save().await?; + + genesis::database::update_configs(init_args.genesis_args.clone(), shell, chain_config).await?; update_portal_config(shell, chain_config) .await diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/init/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/init/mod.rs index f115048d1181..b2638e989d3f 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/init/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/init/mod.rs @@ -2,9 +2,10 @@ use anyhow::Context; use clap::{command, Parser, Subcommand}; use xshell::Shell; use zkstack_cli_common::{git, logger, spinner::Spinner}; -use zkstack_cli_config::{traits::SaveConfigWithBasePath, ChainConfig, EcosystemConfig}; +use zkstack_cli_config::{ + get_da_client_type, traits::SaveConfigWithBasePath, ChainConfig, EcosystemConfig, +}; use zkstack_cli_types::{BaseToken, L1BatchCommitmentMode}; -use zksync_config::DAClientConfig; use zksync_types::Address; use crate::{ @@ -175,7 +176,9 @@ pub async fn init( .await?; contracts_config.save_with_base_path(shell, &chain_config.configs)?; - let l1_da_validator_addr = get_l1_da_validator(chain_config); + let l1_da_validator_addr = get_l1_da_validator(chain_config) + .await + .context("l1_da_validator_addr")?; let spinner = Spinner::new(MSG_DA_PAIR_REGISTRATION_SPINNER); set_da_validator_pair( @@ -184,7 +187,7 @@ pub async fn init( contracts_config.l1.chain_admin_addr, &chain_config.get_wallets_config()?.governor, contracts_config.l1.diamond_proxy_addr, - l1_da_validator_addr.context("l1_da_validator_addr")?, + l1_da_validator_addr, contracts_config .l2 .da_validator_addr @@ -245,21 +248,19 @@ pub async fn init( Ok(()) } -pub(crate) fn get_l1_da_validator(chain_config: &ChainConfig) -> anyhow::Result
{ +pub(crate) async fn get_l1_da_validator(chain_config: &ChainConfig) -> anyhow::Result
{ let contracts_config = chain_config.get_contracts_config()?; let l1_da_validator_contract = match chain_config.l1_batch_commit_data_generator_mode { L1BatchCommitmentMode::Rollup => contracts_config.l1.rollup_l1_da_validator_addr, L1BatchCommitmentMode::Validium => { - let general_config = chain_config.get_general_config()?; - if let Some(da_client_config) = general_config.da_client_config { - match da_client_config { - DAClientConfig::Avail(_) => contracts_config.l1.avail_l1_da_validator_addr, - DAClientConfig::NoDA => contracts_config.l1.no_da_validium_l1_validator_addr, - _ => anyhow::bail!("DA client config is not supported"), + let general_config = chain_config.get_general_config().await?; + match get_da_client_type(&general_config) { + Some("avail") => contracts_config.l1.avail_l1_da_validator_addr, + Some("no_da") | None => contracts_config.l1.no_da_validium_l1_validator_addr, + Some(unsupported) => { + anyhow::bail!("DA client config is not supported: {unsupported:?}"); } - } else { - contracts_config.l1.no_da_validium_l1_validator_addr } } } diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/migrate_from_gateway.rs b/zkstack_cli/crates/zkstack/src/commands/chain/migrate_from_gateway.rs index cf9b9e8e6399..b2ebcda80a85 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/migrate_from_gateway.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/migrate_from_gateway.rs @@ -25,14 +25,12 @@ use zkstack_cli_config::{ EcosystemConfig, }; use zkstack_cli_types::L1BatchCommitmentMode; -use zksync_basic_types::{ - pubdata_da::PubdataSendingMode, settlement::SettlementMode, H256, U256, U64, -}; +use zksync_basic_types::{settlement::SettlementMode, H256, U256, U64}; use zksync_types::L2ChainId; use zksync_web3_decl::client::{Client, L2}; use crate::{ - messages::{MSG_CHAIN_NOT_INITIALIZED, MSG_L1_SECRETS_MUST_BE_PRESENTED}, + messages::MSG_CHAIN_NOT_INITIALIZED, utils::forge::{check_the_balance, fill_forge_private_key, WalletOwner}, }; @@ -74,17 +72,14 @@ pub async fn run(args: MigrateFromGatewayArgs, shell: &Shell) -> anyhow::Result< .context("Gateway config not present")?; let l1_url = chain_config - .get_secrets_config()? - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(); + .get_secrets_config() + .await? + .get::("l1.l1_rpc_url")?; - let genesis_config = chain_config.get_genesis_config()?; + let genesis_config = chain_config.get_genesis_config().await?; let is_rollup = matches!( - genesis_config.l1_batch_commit_data_generator_mode, + genesis_config.get("l1_batch_commit_data_generator_mode")?, L1BatchCommitmentMode::Rollup ); @@ -126,29 +121,13 @@ pub async fn run(args: MigrateFromGatewayArgs, shell: &Shell) -> anyhow::Result< ) .await?; - let gateway_provider = Provider::::try_from( - gateway_chain_config - .get_general_config() - .unwrap() - .api_config - .unwrap() - .web3_json_rpc - .http_url, - )?; + let general_config = gateway_chain_config.get_general_config().await?; + let l2_rpc_url = general_config.get::("api.web3_json_rpc.http_url")?; + let gateway_provider = Provider::::try_from(&l2_rpc_url)?; - let client: Client = Client::http( - gateway_chain_config - .get_general_config() - .unwrap() - .api_config - .unwrap() - .web3_json_rpc - .http_url - .parse() - .unwrap(), - )? - .for_network(L2::from(L2ChainId::new(gateway_chain_id).unwrap())) - .build(); + let client: Client = Client::http(l2_rpc_url.parse().context("invalid L2 RPC URL")?)? + .for_network(L2::from(L2ChainId::new(gateway_chain_id).unwrap())) + .build(); if hash == H256::zero() { println!("Chain already migrated!"); @@ -188,43 +167,23 @@ pub async fn run(args: MigrateFromGatewayArgs, shell: &Shell) -> anyhow::Result< gateway_chain_chain_config.gateway_chain_id = 0u64.into(); gateway_chain_chain_config.save_with_base_path(shell, chain_config.configs.clone())?; - let mut general_config = chain_config.get_general_config().unwrap(); - - let eth_config = general_config.eth.as_mut().context("eth")?; - - eth_config - .gas_adjuster - .as_mut() - .expect("gas_adjuster") - .settlement_mode = SettlementMode::SettlesToL1; + let mut general_config = chain_config.get_general_config().await?.patched(); + general_config.insert_yaml( + "eth.gas_adjuster.settlement_mode", + SettlementMode::SettlesToL1, + )?; if is_rollup { - // For rollups, new type of commitment should be used, but - // not for validium. - eth_config - .sender - .as_mut() - .expect("sender") - .pubdata_sending_mode = PubdataSendingMode::Blobs; + // `PubdataSendingMode` has differing `serde` and file-based config serializations, hence + // we supply a raw string value. + general_config.insert("eth.sender.pubdata_sending_mode", "BLOBS")?; } - eth_config - .sender - .as_mut() - .context("sender")? - .wait_confirmations = Some(0); + general_config.insert("eth.sender.wait_confirmations", 0)?; + // Undoing what was changed during migration to gateway. // TODO(EVM-925): maybe remove this logic. - eth_config - .sender - .as_mut() - .expect("sender") - .max_aggregated_tx_gas = 15000000; - eth_config - .sender - .as_mut() - .expect("sender") - .max_eth_tx_data_size = 120_000; - - general_config.save_with_base_path(shell, chain_config.configs.clone())?; + general_config.insert("eth.sender.max_aggregated_tx_gas", 15000000)?; + general_config.insert("eth.sender.max_eth_tx_data_size", 120_000)?; + general_config.save().await?; Ok(()) } diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/migrate_to_gateway.rs b/zkstack_cli/crates/zkstack/src/commands/chain/migrate_to_gateway.rs index c51f6414ce97..0be8c62da627 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/migrate_to_gateway.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/migrate_to_gateway.rs @@ -24,14 +24,12 @@ use zkstack_cli_config::{ EcosystemConfig, }; use zkstack_cli_types::L1BatchCommitmentMode; -use zksync_basic_types::{ - pubdata_da::PubdataSendingMode, settlement::SettlementMode, Address, H256, U256, U64, -}; +use zksync_basic_types::{settlement::SettlementMode, Address, H256, U256, U64}; use zksync_config::configs::gateway::GatewayChainConfig; use zksync_system_constants::L2_BRIDGEHUB_ADDRESS; use crate::{ - messages::{MSG_CHAIN_NOT_INITIALIZED, MSG_L1_SECRETS_MUST_BE_PRESENTED}, + messages::MSG_CHAIN_NOT_INITIALIZED, utils::forge::{check_the_balance, fill_forge_private_key, WalletOwner}, }; @@ -84,14 +82,11 @@ pub async fn run(args: MigrateToGatewayArgs, shell: &Shell) -> anyhow::Result<() .context("Gateway config not present")?; let l1_url = chain_config - .get_secrets_config()? - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(); + .get_secrets_config() + .await? + .get::("l1.l1_rpc_url")?; - let genesis_config = chain_config.get_genesis_config()?; + let genesis_config = chain_config.get_genesis_config().await?; let preparation_config_path = GATEWAY_PREPARATION.input(&ecosystem_config.link_to_code); let preparation_config = GatewayPreparationConfig::new( @@ -176,15 +171,9 @@ pub async fn run(args: MigrateToGatewayArgs, shell: &Shell) -> anyhow::Result<() .await? .governance_l2_tx_hash; - let gateway_provider = Provider::::try_from( - gateway_chain_config - .get_general_config() - .unwrap() - .api_config - .unwrap() - .web3_json_rpc - .http_url, - )?; + let general_config = gateway_chain_config.get_general_config().await?; + let l2_rpc_url = general_config.get::("api.web3_json_rpc.http_url")?; + let gateway_provider = Provider::::try_from(l2_rpc_url.clone())?; if hash == H256::zero() { println!("Chain already migrated!"); @@ -214,7 +203,7 @@ pub async fn run(args: MigrateToGatewayArgs, shell: &Shell) -> anyhow::Result<() let chain_contracts_config = chain_config.get_contracts_config().unwrap(); let is_rollup = matches!( - genesis_config.l1_batch_commit_data_generator_mode, + genesis_config.get("l1_batch_commit_data_generator_mode")?, L1BatchCommitmentMode::Rollup ); @@ -356,19 +345,10 @@ pub async fn run(args: MigrateToGatewayArgs, shell: &Shell) -> anyhow::Result<() hex::encode(hash.as_bytes()) ); - let gateway_url = gateway_chain_config - .get_general_config() - .unwrap() - .api_config - .unwrap() - .web3_json_rpc - .http_url - .clone(); - - let mut chain_secrets_config = chain_config.get_secrets_config().unwrap(); - chain_secrets_config.l1.as_mut().unwrap().gateway_rpc_url = - Some(url::Url::parse(&gateway_url).unwrap().into()); - chain_secrets_config.save_with_base_path(shell, chain_config.configs.clone())?; + let gateway_url = l2_rpc_url; + let mut chain_secrets_config = chain_config.get_secrets_config().await?.patched(); + chain_secrets_config.insert("l1.gateway_rpc_url", gateway_url)?; + chain_secrets_config.save().await?; let gateway_chain_config = GatewayChainConfig::from_gateway_and_chain_data( &gateway_gateway_config, @@ -378,43 +358,21 @@ pub async fn run(args: MigrateToGatewayArgs, shell: &Shell) -> anyhow::Result<() ); gateway_chain_config.save_with_base_path(shell, chain_config.configs.clone())?; - let mut general_config = chain_config.get_general_config().unwrap(); - - let eth_config = general_config.eth.as_mut().context("eth")?; + let mut general_config = chain_config.get_general_config().await?.patched(); + general_config.insert_yaml("eth.gas_adjuster.settlement_mode", SettlementMode::Gateway)?; - eth_config - .gas_adjuster - .as_mut() - .expect("gas_adjuster") - .settlement_mode = SettlementMode::Gateway; if is_rollup { - // For rollups, new type of commitment should be used, but - // not for validium. - eth_config - .sender - .as_mut() - .expect("sender") - .pubdata_sending_mode = PubdataSendingMode::RelayedL2Calldata; + // For rollups, new type of commitment should be used, but not for validium. + // `PubdataSendingMode` has differing `serde` and file-based config serializations, hence + // we supply a raw string value. + general_config.insert("eth.sender.pubdata_sending_mode", "RELAYED_L2_CALLDATA")?; } - eth_config - .sender - .as_mut() - .context("sender")? - .wait_confirmations = Some(0); + general_config.insert("eth.sender.wait_confirmations", 0)?; // TODO(EVM-925): the number below may not always work, especially for large prices on // top of Gateway. This field would have to be either not used on GW or transformed into u64. - eth_config - .sender - .as_mut() - .expect("sender") - .max_aggregated_tx_gas = 4294967295; - eth_config - .sender - .as_mut() - .expect("sender") - .max_eth_tx_data_size = 550_000; - - general_config.save_with_base_path(shell, chain_config.configs.clone())?; + general_config.insert("eth.sender.max_aggregated_tx_gas", 4294967295_u64)?; + general_config.insert("eth.sender.max_eth_tx_data_size", 550_000)?; + general_config.save().await?; Ok(()) } diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/mod.rs index d6c1851d0c96..2c8930f33ceb 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/mod.rs @@ -92,7 +92,7 @@ pub enum ChainCommands { pub(crate) async fn run(shell: &Shell, args: ChainCommands) -> anyhow::Result<()> { match args { - ChainCommands::Create(args) => create::run(args, shell), + ChainCommands::Create(args) => create::run(args, shell).await, ChainCommands::Init(args) => init::run(*args, shell).await, ChainCommands::BuildTransactions(args) => build_transactions::run(args, shell).await, ChainCommands::Genesis(args) => genesis::run(args, shell).await, diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/register_chain.rs b/zkstack_cli/crates/zkstack/src/commands/chain/register_chain.rs index 626d25438385..4711e8645b27 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/register_chain.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/register_chain.rs @@ -15,10 +15,7 @@ use zkstack_cli_config::{ }; use crate::{ - messages::{ - MSG_CHAIN_NOT_INITIALIZED, MSG_CHAIN_REGISTERED, MSG_L1_SECRETS_MUST_BE_PRESENTED, - MSG_REGISTERING_CHAIN_SPINNER, - }, + messages::{MSG_CHAIN_NOT_INITIALIZED, MSG_CHAIN_REGISTERED, MSG_REGISTERING_CHAIN_SPINNER}, utils::forge::{check_the_balance, fill_forge_private_key, WalletOwner}, }; @@ -28,13 +25,8 @@ pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { .load_current_chain() .context(MSG_CHAIN_NOT_INITIALIZED)?; let mut contracts = chain_config.get_contracts_config()?; - let secrets = chain_config.get_secrets_config()?; - let l1_rpc_url = secrets - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(); + let secrets = chain_config.get_secrets_config().await?; + let l1_rpc_url = secrets.get("l1.l1_rpc_url")?; let spinner = Spinner::new(MSG_REGISTERING_CHAIN_SPINNER); register_chain( shell, diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/set_token_multiplier_setter.rs b/zkstack_cli/crates/zkstack/src/commands/chain/set_token_multiplier_setter.rs index e1a57dcd0f00..1d17d179afdc 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/set_token_multiplier_setter.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/set_token_multiplier_setter.rs @@ -15,9 +15,9 @@ use zksync_basic_types::Address; use crate::{ messages::{ - MSG_CHAIN_NOT_INITIALIZED, MSG_L1_SECRETS_MUST_BE_PRESENTED, - MSG_TOKEN_MULTIPLIER_SETTER_UPDATED_TO, MSG_UPDATING_TOKEN_MULTIPLIER_SETTER_SPINNER, - MSG_WALLETS_CONFIG_MUST_BE_PRESENT, MSG_WALLET_TOKEN_MULTIPLIER_SETTER_NOT_FOUND, + MSG_CHAIN_NOT_INITIALIZED, MSG_TOKEN_MULTIPLIER_SETTER_UPDATED_TO, + MSG_UPDATING_TOKEN_MULTIPLIER_SETTER_SPINNER, MSG_WALLETS_CONFIG_MUST_BE_PRESENT, + MSG_WALLET_TOKEN_MULTIPLIER_SETTER_NOT_FOUND, }, utils::forge::{check_the_balance, fill_forge_private_key, WalletOwner}, }; @@ -38,12 +38,9 @@ pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { .context(MSG_CHAIN_NOT_INITIALIZED)?; let contracts_config = chain_config.get_contracts_config()?; let l1_url = chain_config - .get_secrets_config()? - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(); + .get_secrets_config() + .await? + .get("l1.l1_rpc_url")?; let token_multiplier_setter_address = chain_config .get_wallets_config() .context(MSG_WALLETS_CONFIG_MUST_BE_PRESENT)? diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/setup_legacy_bridge.rs b/zkstack_cli/crates/zkstack/src/commands/chain/setup_legacy_bridge.rs index 24ef9d3c16d9..4d3e3cb1bd4e 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/setup_legacy_bridge.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/setup_legacy_bridge.rs @@ -13,7 +13,7 @@ use zkstack_cli_config::{ }; use crate::{ - messages::{MSG_DEPLOYING_PAYMASTER, MSG_L1_SECRETS_MUST_BE_PRESENTED}, + messages::MSG_DEPLOYING_PAYMASTER, utils::forge::{check_the_balance, fill_forge_private_key, WalletOwner}, }; @@ -52,19 +52,12 @@ pub async fn setup_legacy_bridge( }; let foundry_contracts_path = chain_config.path_to_l1_foundry(); input.save(shell, SETUP_LEGACY_BRIDGE.input(&chain_config.link_to_code))?; - let secrets = chain_config.get_secrets_config()?; + let secrets = chain_config.get_secrets_config().await?; let mut forge = Forge::new(&foundry_contracts_path) .script(&SETUP_LEGACY_BRIDGE.script(), forge_args.clone()) .with_ffi() - .with_rpc_url( - secrets - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(), - ) + .with_rpc_url(secrets.get("l1.l1_rpc_url")?) .with_broadcast(); forge = fill_forge_private_key( diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/conv.rs b/zkstack_cli/crates/zkstack/src/commands/consensus/conv.rs deleted file mode 100644 index c9d878c8fd32..000000000000 --- a/zkstack_cli/crates/zkstack/src/commands/consensus/conv.rs +++ /dev/null @@ -1,47 +0,0 @@ -use anyhow::Context as _; -use zksync_config::configs::consensus as config; -use zksync_consensus_crypto::TextFmt as _; -use zksync_consensus_roles::attester; -use zksync_protobuf::{ProtoFmt, ProtoRepr}; - -use super::proto; -use crate::utils::consensus::parse_attester_committee; - -#[derive(Debug, Clone, PartialEq)] -pub(super) struct SetAttesterCommitteeFile { - pub attesters: attester::Committee, -} - -impl ProtoFmt for SetAttesterCommitteeFile { - type Proto = proto::SetAttesterCommitteeFile; - - fn read(r: &Self::Proto) -> anyhow::Result { - // zksync_config was not allowed to depend on consensus crates, - // therefore to parse the config we need to go through the intermediate - // representation of consensus types defined in zksync_config. - let attesters: Vec<_> = r - .attesters - .iter() - .map(|x| x.read()) - .collect::>() - .context("attesters")?; - Ok(Self { - attesters: parse_attester_committee(&attesters)?, - }) - } - - fn build(&self) -> Self::Proto { - Self::Proto { - attesters: self - .attesters - .iter() - .map(|a| { - ProtoRepr::build(&config::WeightedAttester { - key: config::AttesterPublicKey(a.key.encode()), - weight: a.weight, - }) - }) - .collect(), - } - } -} diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs b/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs index ad64207b481c..3a628d561e81 100644 --- a/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs @@ -3,7 +3,6 @@ use std::{borrow::Borrow, collections::HashMap, path::PathBuf, sync::Arc}; /// Consensus registry contract operations. /// Includes code duplicated from `zksync_node_consensus::registry::abi`. use anyhow::Context as _; -use conv::*; use ethers::{ abi::Detokenize, contract::{FunctionCall, Multicall}, @@ -16,15 +15,11 @@ use tokio::time::MissedTickBehavior; use xshell::Shell; use zkstack_cli_common::{config::global_config, logger, wallets::Wallet}; use zkstack_cli_config::EcosystemConfig; +use zksync_basic_types::L2ChainId; use zksync_consensus_crypto::ByteFmt; use zksync_consensus_roles::{attester, validator}; -use crate::{commands::args::WaitArgs, messages, utils::consensus::parse_attester_committee}; - -mod conv; -mod proto; -#[cfg(test)] -mod tests; +use crate::{commands::args::WaitArgs, messages, utils::consensus::read_attester_committee_yaml}; #[allow(warnings)] mod abi { @@ -99,17 +94,20 @@ pub enum Command { /// Collection of sent transactions. #[derive(Default)] -pub struct TxSet(Vec<(H256, &'static str)>); +struct TxSet(Vec<(H256, String)>); impl TxSet { /// Sends a transactions and stores the transaction hash. - pub async fn send, D: Detokenize>( + async fn send, D: Detokenize>( &mut self, - name: &'static str, + name: String, call: FunctionCall, ) -> anyhow::Result<()> { - let h = call.send().await.context(name)?.tx_hash(); - self.0.push((h, name)); + let hash = call.send().await.with_context(|| name.clone())?.tx_hash(); + if global_config().verbose { + logger::debug(format!("Sent transaction {name}: {hash:?}")); + } + self.0.push((hash, name)); Ok(()) } @@ -146,19 +144,14 @@ fn print_attesters(committee: &attester::Committee) { struct Setup { chain: zkstack_cli_config::ChainConfig, contracts: zkstack_cli_config::ContractsConfig, - general: zkstack_cli_config::GeneralConfig, - genesis: zkstack_cli_config::GenesisConfig, + l2_chain_id: L2ChainId, + l2_http_url: String, + genesis_attesters: attester::Committee, } impl Setup { fn provider(&self) -> anyhow::Result> { - let l2_url = &self - .general - .api_config - .as_ref() - .context(messages::MSG_API_CONFIG_MISSING)? - .web3_json_rpc - .http_url; + let l2_url = &self.l2_http_url; Provider::try_from(l2_url).with_context(|| format!("Provider::try_from({l2_url})")) } @@ -173,7 +166,7 @@ impl Setup { .multicall3 .context(messages::MSG_MULTICALL3_CONTRACT_NOT_CONFIGURED)?, ), - Some(self.genesis.l2_chain_id.as_u64()), + Some(self.l2_chain_id.as_u64()), )?) } @@ -186,7 +179,7 @@ impl Setup { } fn signer(&self, wallet: LocalWallet) -> anyhow::Result> { - let wallet = wallet.with_chain_id(self.genesis.l2_chain_id.as_u64()); + let wallet = wallet.with_chain_id(self.l2_chain_id.as_u64()); let provider = self.provider().context("provider()")?; let signer = SignerMiddleware::new(provider, wallet.clone()); // Allows us to send next transaction without waiting for the previous to complete. @@ -194,7 +187,7 @@ impl Setup { Ok(Arc::new(signer)) } - fn new(shell: &Shell) -> anyhow::Result { + async fn new(shell: &Shell) -> anyhow::Result { let ecosystem_config = EcosystemConfig::from_file(shell).context("EcosystemConfig::from_file()")?; let chain = ecosystem_config @@ -203,13 +196,29 @@ impl Setup { let contracts = chain .get_contracts_config() .context("get_contracts_config()")?; - let genesis = chain.get_genesis_config().context("get_genesis_config()")?; - let general = chain.get_general_config().context("get_general_config()")?; + let l2_chain_id = chain + .get_genesis_config() + .await + .context("get_genesis_config()")? + .get("l2_chain_id")?; + + let general = chain + .get_general_config() + .await + .context("get_general_config()")?; + // We're getting a parent path here, since we need object input with the `attesters` array + let genesis_attesters = general + .get_raw("consensus.genesis_spec") + .context(messages::MSG_CONSENSUS_GENESIS_SPEC_ATTESTERS_MISSING_IN_GENERAL_YAML)? + .clone(); + let genesis_attesters = read_attester_committee_yaml(genesis_attesters)?; + Ok(Self { chain, contracts, - general, - genesis, + l2_chain_id, + l2_http_url: general.get("api.web3_json_rpc.http_url")?, + genesis_attesters, }) } @@ -260,26 +269,10 @@ impl Setup { // Fetch the desired state. if let Some(path) = &opts.from_file { let yaml = std::fs::read_to_string(path).context("read_to_string()")?; - let file: SetAttesterCommitteeFile = zksync_protobuf::serde::Deserialize { - deny_unknown_fields: true, - } - .proto_fmt_from_yaml(&yaml) - .context("proto_fmt_from_yaml()")?; - return Ok(file.attesters); + let yaml = serde_yaml::from_str(&yaml).context("parse YAML")?; + return read_attester_committee_yaml(yaml); } - let attesters = (|| { - Some( - &self - .general - .consensus_config - .as_ref()? - .genesis_spec - .as_ref()? - .attesters, - ) - })() - .context(messages::MSG_CONSENSUS_GENESIS_SPEC_ATTESTERS_MISSING_IN_GENERAL_YAML)?; - parse_attester_committee(attesters).context("parse_attester_committee()") + Ok(self.genesis_attesters.clone()) } async fn wait_for_registry_contract_inner( @@ -335,9 +328,21 @@ impl Setup { } async fn set_attester_committee(&self, want: &attester::Committee) -> anyhow::Result<()> { + if global_config().verbose { + logger::debug(format!("Setting attester committee: {want:?}")); + } + let provider = self.provider().context("provider()")?; let block_id = self.last_block(&provider).await.context("last_block()")?; + if global_config().verbose { + logger::debug(format!("Fetched latest L2 block: {block_id:?}")); + } + let governor = self.governor().context("governor()")?; + if global_config().verbose { + logger::debug(format!("Using governor: {:?}", governor.address)); + } + let signer = self.signer( governor .private_key @@ -348,6 +353,13 @@ impl Setup { .consensus_registry(signer.clone()) .context("consensus_registry()")?; let mut multicall = self.multicall(signer).context("multicall()")?; + if global_config().verbose { + logger::debug(format!( + "Using consensus registry at {:?}, multicall at {:?}", + consensus_registry.address(), + multicall.contract.address() + )); + } let owner = consensus_registry.owner().call().await.context("owner()")?; if owner != governor.address { @@ -368,6 +380,11 @@ impl Setup { .try_into() .ok() .context("num_nodes() overflow")?; + if global_config().verbose { + logger::debug(format!( + "Fetched number of nodes from consensus registry: {n}" + )); + } multicall.block = Some(block_id); let node_owners: Vec
= multicall @@ -379,6 +396,12 @@ impl Setup { .await .context("node_owners()")?; multicall.clear_calls(); + if global_config().verbose { + logger::debug(format!( + "Fetched node owners from consensus registry: {node_owners:?}" + )); + } + let nodes: Vec = multicall .add_calls( false, @@ -390,6 +413,11 @@ impl Setup { .await .context("nodes()")?; multicall.clear_calls(); + if global_config().verbose { + logger::debug(format!( + "Fetched node info from consensus registry: {nodes:?}" + )); + } // Update the state. let mut txs = TxSet::default(); @@ -398,15 +426,21 @@ impl Setup { if node.attester_latest.removed { continue; } + + let node_owner = node_owners[i]; let got = attester::WeightedAttester { key: decode_attester_key(&node.attester_latest.pub_key) .context("decode_attester_key()")?, weight: node.attester_latest.weight.into(), }; + if let Some(weight) = to_insert.remove(&got.key) { if weight != got.weight { txs.send( - "changed_attester_weight", + format!( + "change_attester_weight({node_owner:?}, {} -> {weight})", + got.weight + ), consensus_registry.change_attester_weight( node_owners[i], weight.try_into().context("weight overflow")?, @@ -415,18 +449,24 @@ impl Setup { .await?; } if !node.attester_latest.active { - txs.send("activate", consensus_registry.activate(node_owners[i])) - .await?; + txs.send( + format!("activate({node_owner:?})"), + consensus_registry.activate(node_owner), + ) + .await?; } } else { - txs.send("remove", consensus_registry.remove(node_owners[i])) - .await?; + txs.send( + format!("remove({node_owner:?})"), + consensus_registry.remove(node_owner), + ) + .await?; } } for (key, weight) in to_insert { let vk = validator::SecretKey::generate(); txs.send( - "add", + format!("add({key:?}, {weight})"), consensus_registry.add( Address::random(), /*validator_weight=*/ 1, @@ -439,7 +479,7 @@ impl Setup { .await?; } txs.send( - "commit_attester_committee", + "commit_attester_committee".to_owned(), consensus_registry.commit_attester_committee(), ) .await?; @@ -450,7 +490,7 @@ impl Setup { impl Command { pub(crate) async fn run(self, shell: &Shell) -> anyhow::Result<()> { - let setup = Setup::new(shell).context("Setup::new()")?; + let setup = Setup::new(shell).await?; match self { Self::SetAttesterCommittee(opts) => { let want = setup diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.proto b/zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.proto deleted file mode 100644 index d8a7323f7144..000000000000 --- a/zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.proto +++ /dev/null @@ -1,9 +0,0 @@ -syntax = "proto3"; - -package zksync.toolbox.consensus; - -import "zksync/core/consensus.proto"; - -message SetAttesterCommitteeFile { - repeated core.consensus.WeightedAttester attesters = 1; -} diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.rs b/zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.rs deleted file mode 100644 index 61a0a047f0a9..000000000000 --- a/zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow(warnings)] - -include!(concat!( - env!("OUT_DIR"), - "/src/commands/consensus/proto/gen.rs" -)); diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/tests.rs b/zkstack_cli/crates/zkstack/src/commands/consensus/tests.rs deleted file mode 100644 index c2f393ad2294..000000000000 --- a/zkstack_cli/crates/zkstack/src/commands/consensus/tests.rs +++ /dev/null @@ -1,19 +0,0 @@ -use rand::{distributions::Distribution, Rng}; -use zksync_consensus_utils::EncodeDist; -use zksync_protobuf::testonly::{test_encode_all_formats, FmtConv}; - -use super::SetAttesterCommitteeFile; - -impl Distribution for EncodeDist { - fn sample(&self, rng: &mut R) -> SetAttesterCommitteeFile { - SetAttesterCommitteeFile { - attesters: rng.gen(), - } - } -} - -#[test] -fn test_encoding() { - let rng = &mut rand::thread_rng(); - test_encode_all_formats::>(rng); -} diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/build.rs b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/build.rs index 384e9a389265..2e4107383d0a 100644 --- a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/build.rs +++ b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/build.rs @@ -13,7 +13,7 @@ pub(crate) async fn build(shell: &Shell) -> anyhow::Result<()> { let chain = ecosystem .load_current_chain() .context(MSG_CHAIN_NOT_FOUND_ERR)?; - let _dir_guard = shell.push_dir(&chain.link_to_code); + let _dir_guard = shell.push_dir(chain.link_to_code.join("core")); logger::info(MSG_BUILDING_CONTRACT_VERIFIER); diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/run.rs b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/run.rs index fd872aa67248..fe4221e83a46 100644 --- a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/run.rs +++ b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/run.rs @@ -22,7 +22,7 @@ pub(crate) async fn run(shell: &Shell) -> anyhow::Result<()> { let mut cmd = Cmd::new(cmd!( shell, - "cargo run --release --bin zksync_contract_verifier -- --config-path={config_path} --secrets-path={secrets_path}" + "cargo run --manifest-path ./core/Cargo.toml --release --bin zksync_contract_verifier -- --config-path={config_path} --secrets-path={secrets_path}" )); cmd = cmd.with_force_run(); cmd.run().context(MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR) diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/wait.rs b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/wait.rs index 0b844df61f4c..070d64b5bdb4 100644 --- a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/wait.rs +++ b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/wait.rs @@ -13,11 +13,9 @@ pub(crate) async fn wait(shell: &Shell, args: WaitArgs) -> anyhow::Result<()> { let verbose = global_config().verbose; let prometheus_port = chain - .get_general_config()? - .contract_verifier - .as_ref() - .context("contract verifier config not specified")? - .prometheus_port; + .get_general_config() + .await? + .get("contract_verifier.prometheus_port")?; logger::info("Waiting for contract verifier to become alive"); args.poll_prometheus(prometheus_port, verbose).await?; logger::info(format!( diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/check_sqlx_data.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/check_sqlx_data.rs index abead3fe00d6..8957fc46ede9 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/check_sqlx_data.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/check_sqlx_data.rs @@ -14,7 +14,7 @@ use crate::commands::dev::{ }, }; -pub fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { +pub async fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { let args = args.parse(); if args.selected_dals.none() { logger::outro(MSG_NO_DATABASES_SELECTED); @@ -25,7 +25,7 @@ pub fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { logger::info(msg_database_info(MSG_DATABASE_CHECK_SQLX_DATA_GERUND)); - let dals = get_dals(shell, &args.selected_dals, &args.urls)?; + let dals = get_dals(shell, &args.selected_dals, &args.urls).await?; for dal in dals { check_sqlx_data(shell, &ecosystem_config.link_to_code, dal)?; } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/drop.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/drop.rs index e46a434cec06..f2bf647ed726 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/drop.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/drop.rs @@ -23,7 +23,7 @@ pub async fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> logger::info(msg_database_info(MSG_DATABASE_DROP_GERUND)); - let dals = get_dals(shell, &args.selected_dals, &args.urls)?; + let dals = get_dals(shell, &args.selected_dals, &args.urls).await?; for dal in dals { drop_database(dal).await?; } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/migrate.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/migrate.rs index 8c21262c0712..3ebb30c3dfe3 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/migrate.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/migrate.rs @@ -13,7 +13,7 @@ use crate::commands::dev::{ }, }; -pub fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { +pub async fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { let args = args.parse(); if args.selected_dals.none() { logger::outro(MSG_NO_DATABASES_SELECTED); @@ -23,7 +23,7 @@ pub fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { logger::info(msg_database_info(MSG_DATABASE_MIGRATE_GERUND)); let ecosystem_config = EcosystemConfig::from_file(shell)?; - let dals = get_dals(shell, &args.selected_dals, &args.urls)?; + let dals = get_dals(shell, &args.selected_dals, &args.urls).await?; for dal in dals { migrate_database(shell, &ecosystem_config.link_to_code, dal)?; } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/mod.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/mod.rs index ed039fc65019..909b6fa5bc22 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/mod.rs @@ -37,12 +37,12 @@ pub enum DatabaseCommands { pub async fn run(shell: &Shell, args: DatabaseCommands) -> anyhow::Result<()> { match args { - DatabaseCommands::CheckSqlxData(args) => check_sqlx_data::run(shell, args), + DatabaseCommands::CheckSqlxData(args) => check_sqlx_data::run(shell, args).await, DatabaseCommands::Drop(args) => drop::run(shell, args).await, - DatabaseCommands::Migrate(args) => migrate::run(shell, args), - DatabaseCommands::NewMigration(args) => new_migration::run(shell, args), - DatabaseCommands::Prepare(args) => prepare::run(shell, args), + DatabaseCommands::Migrate(args) => migrate::run(shell, args).await, + DatabaseCommands::NewMigration(args) => new_migration::run(shell, args).await, + DatabaseCommands::Prepare(args) => prepare::run(shell, args).await, DatabaseCommands::Reset(args) => reset::run(shell, args).await, - DatabaseCommands::Setup(args) => setup::run(shell, args), + DatabaseCommands::Setup(args) => setup::run(shell, args).await, } } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/new_migration.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/new_migration.rs index 655a841e060a..809886eb5e2f 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/new_migration.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/new_migration.rs @@ -10,12 +10,12 @@ use crate::commands::dev::{ messages::{msg_database_new_migration_loading, MSG_DATABASE_NEW_MIGRATION_SUCCESS}, }; -pub fn run(shell: &Shell, args: DatabaseNewMigrationArgs) -> anyhow::Result<()> { +pub async fn run(shell: &Shell, args: DatabaseNewMigrationArgs) -> anyhow::Result<()> { let args = args.fill_values_with_prompt(); let dal = match args.selected_database { - SelectedDatabase::Core => get_core_dal(shell, None)?, - SelectedDatabase::Prover => get_prover_dal(shell, None)?, + SelectedDatabase::Core => get_core_dal(shell, None).await?, + SelectedDatabase::Prover => get_prover_dal(shell, None).await?, }; let ecosystem_config = EcosystemConfig::from_file(shell)?; diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/prepare.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/prepare.rs index 82c9ed2e338b..1d2c2d57cb03 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/prepare.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/prepare.rs @@ -13,7 +13,7 @@ use crate::commands::dev::{ }, }; -pub fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { +pub async fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { let args = args.parse(); if args.selected_dals.none() { logger::outro(MSG_NO_DATABASES_SELECTED); @@ -24,7 +24,7 @@ pub fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { logger::info(msg_database_info(MSG_DATABASE_PREPARE_GERUND)); - let dals = get_dals(shell, &args.selected_dals, &args.urls)?; + let dals = get_dals(shell, &args.selected_dals, &args.urls).await?; for dal in dals { prepare_sqlx_data(shell, &ecosystem_config.link_to_code, dal)?; } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/reset.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/reset.rs index 4a9ec022d723..c9d5ad112ae3 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/reset.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/reset.rs @@ -24,7 +24,7 @@ pub async fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> logger::info(msg_database_info(MSG_DATABASE_RESET_GERUND)); - let dals = get_dals(shell, &args.selected_dals, &args.urls)?; + let dals = get_dals(shell, &args.selected_dals, &args.urls).await?; for dal in dals { logger::info(msg_database_loading(MSG_DATABASE_RESET_GERUND, &dal.path)); reset_database(shell, ecosystem_config.link_to_code.clone(), dal).await?; diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/setup.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/setup.rs index 4eba9b615fc0..ca44273ebf1a 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/setup.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/database/setup.rs @@ -13,7 +13,7 @@ use crate::commands::dev::{ }, }; -pub fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { +pub async fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { let args = args.parse(); if args.selected_dals.none() { logger::outro(MSG_NO_DATABASES_SELECTED); @@ -24,7 +24,7 @@ pub fn run(shell: &Shell, args: DatabaseCommonArgs) -> anyhow::Result<()> { logger::info(msg_database_info(MSG_DATABASE_SETUP_GERUND)); - let dals = get_dals(shell, &args.selected_dals, &args.urls)?; + let dals = get_dals(shell, &args.selected_dals, &args.urls).await?; for dal in dals { setup_database(shell, &ecosystem_config.link_to_code, dal)?; } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/fmt.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/fmt.rs index af6985b006d2..82594cccf484 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/fmt.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/fmt.rs @@ -42,7 +42,7 @@ async fn prettier_contracts(shell: Shell, check: bool) -> anyhow::Result<()> { } async fn rustfmt(shell: Shell, check: bool, link_to_code: PathBuf) -> anyhow::Result<()> { - for dir in [".", "prover", "zkstack_cli"] { + for dir in ["core", "prover", "zkstack_cli"] { let spinner = Spinner::new(&msg_running_rustfmt_for_dir_spinner(dir)); let _dir = shell.push_dir(link_to_code.join(dir)); let mut cmd = cmd!(shell, "cargo fmt -- --config imports_granularity=Crate --config group_imports=StdExternalCrate"); diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/genesis.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/genesis.rs index 8e7a3973e037..29e5f734e528 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/genesis.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/genesis.rs @@ -18,7 +18,7 @@ pub(crate) async fn run(shell: &Shell) -> anyhow::Result<()> { .context(MSG_CHAIN_NOT_FOUND_ERR)?; let spinner = Spinner::new(MSG_GENESIS_FILE_GENERATION_STARTED); let secrets_path = chain.path_to_secrets_config(); - let dal = get_core_dal(shell, None)?; + let dal = get_core_dal(shell, None).await?; reset_database(shell, ecosystem.link_to_code, dal).await?; Cmd::new(cmd!(shell,"cargo run --package genesis_generator --bin genesis_generator -- --config-path={secrets_path}")).run()?; spinner.finish(); diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint.rs index 6b919b8cdb9d..7ba6fe27481a 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/lint.rs @@ -70,12 +70,12 @@ pub fn run(shell: &Shell, args: LintArgs) -> anyhow::Result<()> { fn lint_rs(shell: &Shell, ecosystem: &EcosystemConfig, check: bool) -> anyhow::Result<()> { let spinner = Spinner::new(&msg_running_linter_for_extension_spinner(&Target::Rs)); - let link_to_code = &ecosystem.link_to_code; + let link_to_core = &ecosystem.link_to_code.join("core"); let lint_to_prover = &ecosystem.link_to_code.join("prover"); let link_to_zkstack = &ecosystem.link_to_code.join("zkstack_cli"); spinner.freeze(); - for path in [link_to_code, lint_to_prover, link_to_zkstack] { + for path in [link_to_core, lint_to_prover, link_to_zkstack] { let _dir_guard = shell.push_dir(path); let mut cmd = cmd!(shell, "cargo clippy"); let mut common_args = vec!["--locked", "--", "-D", "warnings"]; diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/prover/info.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/prover/info.rs index 44d80d48d0ce..d90b350b0192 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/prover/info.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/prover/info.rs @@ -84,14 +84,7 @@ pub(crate) async fn get_fflonk_snark_wrapper(link_to_prover: &Path) -> anyhow::R } pub(crate) async fn get_database_url(chain: &ChainConfig) -> anyhow::Result { - let prover_url = chain - .get_secrets_config()? - .database - .context("Database secrets not found")? - .prover_url()? - .expose_url() - .to_string(); - Ok(prover_url) + chain.get_secrets_config().await?.get("database.prover_url") } pub fn parse_version(version: &str) -> anyhow::Result<(&str, &str)> { diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/snapshot.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/snapshot.rs index dcc41af228be..85aaec103c0b 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/snapshot.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/snapshot.rs @@ -32,7 +32,7 @@ async fn create(shell: &Shell) -> anyhow::Result<()> { logger::info(MSG_RUNNING_SNAPSHOT_CREATOR); - let mut cmd = Cmd::new(cmd!(shell, "cargo run --bin snapshots_creator --release -- --config-path={config_path} --secrets-path={secrets_path}")) + let mut cmd = Cmd::new(cmd!(shell, "cargo run --manifest-path ./core/Cargo.toml --bin snapshots_creator --release -- --config-path={config_path} --secrets-path={secrets_path}")) .env("RUST_LOG", "snapshots_creator=debug"); cmd = cmd.with_force_run(); diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/status/args.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/status/args.rs index 1cc65f194cdc..8395796781da 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/status/args.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/status/args.rs @@ -4,9 +4,7 @@ use xshell::Shell; use zkstack_cli_config::EcosystemConfig; use crate::{ - commands::dev::messages::{ - MSG_API_CONFIG_NOT_FOUND_ERR, MSG_STATUS_PORTS_HELP, MSG_STATUS_URL_HELP, - }, + commands::dev::messages::{MSG_STATUS_PORTS_HELP, MSG_STATUS_URL_HELP}, messages::MSG_CHAIN_NOT_FOUND_ERR, }; @@ -25,7 +23,7 @@ pub struct StatusArgs { } impl StatusArgs { - pub fn get_url(&self, shell: &Shell) -> anyhow::Result { + pub async fn get_url(&self, shell: &Shell) -> anyhow::Result { if let Some(url) = &self.url { Ok(url.clone()) } else { @@ -33,13 +31,9 @@ impl StatusArgs { let chain = ecosystem .load_current_chain() .context(MSG_CHAIN_NOT_FOUND_ERR)?; - let general_config = chain.get_general_config()?; - let health_check_port = general_config - .api_config - .context(MSG_API_CONFIG_NOT_FOUND_ERR)? - .healthcheck - .port; - Ok(format!("http://localhost:{}/health", health_check_port)) + let general_config = chain.get_general_config().await?; + let health_check_port = general_config.get::("api.healthcheck.port")?; + Ok(format!("http://localhost:{health_check_port}/health")) } } } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/status/mod.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/status/mod.rs index 7f2db7533655..7de264ca8252 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/status/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/status/mod.rs @@ -129,7 +129,7 @@ pub async fn run(shell: &Shell, args: StatusArgs) -> anyhow::Result<()> { return print_ports(shell); } - let health_check_url = args.get_url(shell)?; + let health_check_url = args.get_url(shell).await?; print_status(health_check_url) } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/loadtest.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/loadtest.rs index 385335890c75..07a0ae192618 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/loadtest.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/loadtest.rs @@ -5,40 +5,46 @@ use zkstack_cli_config::EcosystemConfig; use crate::commands::dev::messages::MSG_CHAIN_NOT_FOUND_ERR; -pub fn run(shell: &Shell) -> anyhow::Result<()> { +pub async fn run(shell: &Shell) -> anyhow::Result<()> { let ecosystem_config = EcosystemConfig::from_file(shell)?; let chain_config = ecosystem_config .load_current_chain() .context(MSG_CHAIN_NOT_FOUND_ERR)?; - let general_api = chain_config - .get_general_config()? - .api_config - .context("API config is not found")?; - - let mut command = cmd!(shell, "cargo run --release --bin loadnext") - .env( - "L2_CHAIN_ID", - chain_config - .get_genesis_config()? - .l2_chain_id - .as_u64() - .to_string(), - ) - .env( - "MAIN_TOKEN", - format!( - "{:?}", - ecosystem_config - .get_erc20_tokens() - .first() - .context("NO Erc20 tokens were deployed")? - .address - ), - ) - .env("L2_RPC_ADDRESS", general_api.web3_json_rpc.http_url) - .env("L2_WS_RPC_ADDRESS", general_api.web3_json_rpc.ws_url); + let general_config = chain_config.get_general_config().await?; + + let mut command = cmd!( + shell, + "cargo run --manifest-path ./core/Cargo.toml --release --bin loadnext" + ) + .env( + "L2_CHAIN_ID", + chain_config + .get_genesis_config() + .await? + .get::("l2_chain_id")? + .to_string(), + ) + .env( + "MAIN_TOKEN", + format!( + "{:?}", + ecosystem_config + .get_erc20_tokens() + .first() + .context("NO Erc20 tokens were deployed")? + .address + ), + ) + .env( + "L2_RPC_ADDRESS", + general_config.get::("api.web3_json_rpc.http_url")?, + ) + .env( + "L2_WS_RPC_ADDRESS", + general_config.get::("api.web3_json_rpc.ws_url")?, + ); if global_config().verbose { command = command.env("RUST_LOG", "loadnext=info") diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/mod.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/mod.rs index 095e27652aa0..90f9971508d3 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/mod.rs @@ -64,6 +64,6 @@ pub async fn run(shell: &Shell, args: TestCommands) -> anyhow::Result<()> { TestCommands::L1Contracts => l1_contracts::run(shell), TestCommands::Prover => prover::run(shell).await, TestCommands::Wallet => wallet::run(shell), - TestCommands::Loadtest => loadtest::run(shell), + TestCommands::Loadtest => loadtest::run(shell).await, } } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/rust.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/rust.rs index c415eb7407d2..7b93ebf974d6 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/rust.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/rust.rs @@ -11,10 +11,7 @@ use crate::commands::dev::{ commands::test::db::reset_test_databases, dals::{Dal, CORE_DAL_PATH, PROVER_DAL_PATH}, defaults::{TEST_DATABASE_PROVER_URL, TEST_DATABASE_SERVER_URL}, - messages::{ - MSG_CHAIN_NOT_FOUND_ERR, MSG_POSTGRES_CONFIG_NOT_FOUND_ERR, MSG_UNIT_TESTS_RUN_SUCCESS, - MSG_USING_CARGO_NEXTEST, - }, + messages::{MSG_CHAIN_NOT_FOUND_ERR, MSG_UNIT_TESTS_RUN_SUCCESS, MSG_USING_CARGO_NEXTEST}, }; pub async fn run(shell: &Shell, args: RustArgs) -> anyhow::Result<()> { @@ -23,21 +20,13 @@ pub async fn run(shell: &Shell, args: RustArgs) -> anyhow::Result<()> { .clone() .load_chain(Some(ecosystem.default_chain)) .context(MSG_CHAIN_NOT_FOUND_ERR)?; - let general_config = chain.get_general_config(); + let general_config = chain.get_general_config().await; let link_to_code = ecosystem.link_to_code; let (test_server_url, test_prover_url) = if let Ok(general_config) = general_config { - let postgres = general_config - .postgres_config - .context(MSG_POSTGRES_CONFIG_NOT_FOUND_ERR)?; - ( - postgres - .test_server_url - .context(MSG_POSTGRES_CONFIG_NOT_FOUND_ERR)?, - postgres - .test_prover_url - .context(MSG_POSTGRES_CONFIG_NOT_FOUND_ERR)?, + general_config.get::("postgres.test.server_url")?, + general_config.get::("postgres.test.prover_url")?, ) } else { ( @@ -59,7 +48,7 @@ pub async fn run(shell: &Shell, args: RustArgs) -> anyhow::Result<()> { reset_test_databases(shell, &link_to_code, dals).await?; - let _dir_guard = shell.push_dir(&link_to_code); + let _dir_guard = shell.push_dir(link_to_code.join("core")); logger::info(MSG_USING_CARGO_NEXTEST); let cmd = cmd!(shell, "cargo nextest run --release"); diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/utils.rs b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/utils.rs index 7c042fad1fa9..871466d72c23 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/utils.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/commands/test/utils.rs @@ -56,12 +56,9 @@ impl TestWallets { let wallet = self.get_test_wallet(chain_config)?; let l1_rpc = chain_config - .get_secrets_config()? - .l1 - .context("No L1 secrets available")? - .l1_rpc_url - .expose_str() - .to_owned(); + .get_secrets_config() + .await? + .get::("l1.l1_rpc_url")?; let provider = Provider::::try_from(l1_rpc.clone())?; let balance = provider.get_balance(wallet.address, None).await?; diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/dals.rs b/zkstack_cli/crates/zkstack/src/commands/dev/dals.rs index 199c44bbeb70..0d1c505557f2 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/dals.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/dals.rs @@ -1,12 +1,9 @@ use anyhow::Context as _; use url::Url; use xshell::Shell; -use zkstack_cli_config::{EcosystemConfig, SecretsConfig}; +use zkstack_cli_config::{raw::RawConfig, EcosystemConfig}; -use super::{ - commands::database::args::DalUrls, - messages::{MSG_CHAIN_NOT_FOUND_ERR, MSG_DATABASE_MUST_BE_PRESENTED}, -}; +use super::{commands::database::args::DalUrls, messages::MSG_CHAIN_NOT_FOUND_ERR}; pub const CORE_DAL_PATH: &str = "core/lib/dal"; pub const PROVER_DAL_PATH: &str = "prover/crates/lib/prover_dal"; @@ -30,7 +27,7 @@ pub struct Dal { pub url: Url, } -pub fn get_dals( +pub async fn get_dals( shell: &Shell, selected_dals: &SelectedDals, urls: &DalUrls, @@ -38,27 +35,21 @@ pub fn get_dals( let mut dals = vec![]; if selected_dals.prover { - dals.push(get_prover_dal(shell, urls.prover.clone())?); + dals.push(get_prover_dal(shell, urls.prover.clone()).await?); } if selected_dals.core { - dals.push(get_core_dal(shell, urls.core.clone())?); + dals.push(get_core_dal(shell, urls.core.clone()).await?); } Ok(dals) } -pub fn get_prover_dal(shell: &Shell, url: Option) -> anyhow::Result { +pub async fn get_prover_dal(shell: &Shell, url: Option) -> anyhow::Result { let url = if let Some(url) = url { Url::parse(&url)? } else { - let secrets = get_secrets(shell)?; - secrets - .database - .as_ref() - .context(MSG_DATABASE_MUST_BE_PRESENTED)? - .prover_url()? - .expose_url() - .clone() + let secrets = get_secrets(shell).await?; + secrets.get("database.prover_url")? }; Ok(Dal { @@ -67,18 +58,12 @@ pub fn get_prover_dal(shell: &Shell, url: Option) -> anyhow::Result }) } -pub fn get_core_dal(shell: &Shell, url: Option) -> anyhow::Result { +pub async fn get_core_dal(shell: &Shell, url: Option) -> anyhow::Result { let url = if let Some(url) = url { Url::parse(&url)? } else { - let secrets = get_secrets(shell)?; - secrets - .database - .as_ref() - .context(MSG_DATABASE_MUST_BE_PRESENTED)? - .master_url()? - .expose_url() - .clone() + let secrets = get_secrets(shell).await?; + secrets.get("database.server_url")? }; Ok(Dal { @@ -87,12 +72,10 @@ pub fn get_core_dal(shell: &Shell, url: Option) -> anyhow::Result { }) } -fn get_secrets(shell: &Shell) -> anyhow::Result { +async fn get_secrets(shell: &Shell) -> anyhow::Result { let ecosystem_config = EcosystemConfig::from_file(shell)?; let chain_config = ecosystem_config .load_current_chain() .context(MSG_CHAIN_NOT_FOUND_ERR)?; - let secrets = chain_config.get_secrets_config()?; - - Ok(secrets) + chain_config.get_secrets_config().await } diff --git a/zkstack_cli/crates/zkstack/src/commands/dev/messages.rs b/zkstack_cli/crates/zkstack/src/commands/dev/messages.rs index 5a953ab8e215..ec8f0c887536 100644 --- a/zkstack_cli/crates/zkstack/src/commands/dev/messages.rs +++ b/zkstack_cli/crates/zkstack/src/commands/dev/messages.rs @@ -50,7 +50,6 @@ pub(super) const MSG_DATABASE_RESET_GERUND: &str = "Resetting"; pub(super) const MSG_DATABASE_RESET_PAST: &str = "reset"; pub(super) const MSG_DATABASE_SETUP_GERUND: &str = "Setting up"; pub(super) const MSG_DATABASE_SETUP_PAST: &str = "set up"; -pub(super) const MSG_DATABASE_MUST_BE_PRESENTED: &str = "Database config must be presented"; pub(super) const MSG_DATABASE_COMMON_PROVER_HELP: &str = "Prover database"; pub(super) const MSG_DATABASE_COMMON_PROVER_URL_HELP: &str = "URL of the Prover database. If not specified, it is used from the current chain's secrets"; @@ -107,7 +106,6 @@ pub(super) const MSG_L1_CONTRACTS_ABOUT: &str = "Run L1 contracts tests"; pub(super) const MSG_L1_CONTRACTS_TEST_SUCCESS: &str = "L1 contracts tests ran successfully"; pub(super) const MSG_PROVER_TEST_ABOUT: &str = "Run prover tests"; pub(super) const MSG_PROVER_TEST_SUCCESS: &str = "Prover tests ran successfully"; -pub(super) const MSG_POSTGRES_CONFIG_NOT_FOUND_ERR: &str = "Postgres config not found"; pub(super) const MSG_RESETTING_TEST_DATABASES: &str = "Resetting test databases"; // Contract building related messages @@ -237,7 +235,6 @@ pub(super) const MSG_INVALID_L1_RPC_URL_ERR: &str = "Invalid L1 RPC URL"; // Status related messages pub(super) const MSG_STATUS_ABOUT: &str = "Get status of the server"; -pub(super) const MSG_API_CONFIG_NOT_FOUND_ERR: &str = "API config not found"; pub(super) const MSG_STATUS_URL_HELP: &str = "URL of the health check endpoint"; pub(super) const MSG_STATUS_PORTS_HELP: &str = "Show used ports"; pub(super) const MSG_COMPONENTS: &str = "Components:\n"; diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/common.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/common.rs index 7255ba9e1ca5..f8c45cfcf8bd 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/common.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/common.rs @@ -1,16 +1,16 @@ -use anyhow::Context; use xshell::Shell; use zkstack_cli_common::forge::{Forge, ForgeScriptArgs}; use zkstack_cli_config::{ forge_interface::{ deploy_ecosystem::{ - input::{DeployL1Config, InitialDeploymentConfig}, + input::{DeployL1Config, GenesisInput, InitialDeploymentConfig}, output::DeployL1Output, }, script_params::DEPLOY_ECOSYSTEM_SCRIPT_PARAMS, }, - traits::{ReadConfig, ReadConfigWithBasePath, SaveConfig}, - ContractsConfig, EcosystemConfig, GenesisConfig, + raw::RawConfig, + traits::{ReadConfig, SaveConfig}, + ContractsConfig, EcosystemConfig, GENESIS_FILE, }; use zkstack_cli_types::{L1Network, ProverMode}; @@ -28,15 +28,14 @@ pub async fn deploy_l1( support_l2_legacy_shared_bridge_test: bool, ) -> anyhow::Result { let deploy_config_path = DEPLOY_ECOSYSTEM_SCRIPT_PARAMS.input(&config.link_to_code); - dbg!(config.get_default_configs_path()); - let default_genesis_config = - GenesisConfig::read_with_base_path(shell, config.get_default_configs_path()) - .context("failed reading genesis config")?; + let genesis_config_path = config.get_default_configs_path().join(GENESIS_FILE); + let default_genesis_config = RawConfig::read(shell, genesis_config_path).await?; + let default_genesis_input = GenesisInput::new(&default_genesis_config)?; let wallets_config = config.get_wallets()?; // For deploying ecosystem we only need genesis batch params let deploy_config = DeployL1Config::new( - &default_genesis_config, + &default_genesis_input, &wallets_config, initial_deployment_config, config.era_chain_id, diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/create.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/create.rs index 404589afac2d..3bd936f69cb7 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/create.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/create.rs @@ -27,19 +27,19 @@ use crate::{ utils::link_to_code::resolve_link_to_code, }; -pub fn run(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { +pub async fn run(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { match EcosystemConfig::from_file(shell) { Ok(_) => bail!(MSG_ECOSYSTEM_ALREADY_EXISTS_ERR), Err(EcosystemConfigFromFileError::InvalidConfig { .. }) => { bail!(MSG_ECOSYSTEM_CONFIG_INVALID_ERR) } - Err(EcosystemConfigFromFileError::NotExists { .. }) => create(args, shell)?, + Err(EcosystemConfigFromFileError::NotExists { .. }) => create(args, shell).await?, }; Ok(()) } -fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { +async fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { let args = args .fill_values_with_prompt(shell) .context(MSG_ARGS_VALIDATOR_ERR)?; @@ -96,7 +96,7 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { spinner.finish(); let spinner = Spinner::new(MSG_CREATING_DEFAULT_CHAIN_SPINNER); - create_chain_inner(chain_config, &ecosystem_config, shell)?; + create_chain_inner(chain_config, &ecosystem_config, shell).await?; spinner.finish(); if args.start_containers { diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/gateway_upgrade.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/gateway_upgrade.rs index 01905afb9a5d..b8179ca4db83 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/gateway_upgrade.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/gateway_upgrade.rs @@ -6,6 +6,7 @@ use xshell::Shell; use zkstack_cli_common::{db::DatabaseConfig, forge::Forge, git, spinner::Spinner}; use zkstack_cli_config::{ forge_interface::{ + deploy_ecosystem::input::GenesisInput, gateway_ecosystem_upgrade::{ input::GatewayEcosystemUpgradeInput, output::GatewayEcosystemUpgradeOutput, }, @@ -14,8 +15,9 @@ use zkstack_cli_config::{ FINALIZE_UPGRADE_SCRIPT_PARAMS, GATEWAY_PREPARATION, GATEWAY_UPGRADE_ECOSYSTEM_PARAMS, }, }, + raw::RawConfig, traits::{ReadConfig, ReadConfigWithBasePath, SaveConfig, SaveConfigWithBasePath}, - EcosystemConfig, GenesisConfig, CONFIGS_PATH, + EcosystemConfig, GENESIS_FILE, }; use zkstack_cli_types::ProverMode; use zksync_basic_types::commitment::L1BatchCommitmentMode; @@ -95,7 +97,11 @@ async fn no_governance_prepare( let forge_args = init_args.forge_args.clone(); let l1_rpc_url = init_args.l1_rpc_url.clone(); - let new_genesis_config = GenesisConfig::read_with_base_path(shell, CONFIGS_PATH)?; + let genesis_config_path = ecosystem_config + .get_default_configs_path() + .join(GENESIS_FILE); + let default_genesis_config = RawConfig::read(shell, genesis_config_path).await?; + let default_genesis_input = GenesisInput::new(&default_genesis_config)?; let current_contracts_config = ecosystem_config.get_contracts_config()?; let initial_deployment_config = ecosystem_config.get_initial_deployment_config()?; @@ -110,7 +116,7 @@ async fn no_governance_prepare( // assert_eq!(era_config.chain_id, ecosystem_config.era_chain_id); let gateway_upgrade_input = GatewayEcosystemUpgradeInput::new( - &new_genesis_config, + &default_genesis_input, ¤t_contracts_config, &initial_deployment_config, ecosystem_config.era_chain_id, @@ -492,7 +498,8 @@ async fn no_governance_stage_3( .load_chain(Some("gateway".to_string())) .context(MSG_CHAIN_NOT_FOUND_ERR)?; - let chain_genesis_config = chain_config.get_genesis_config()?; + let chain_genesis_config = chain_config.get_genesis_config().await?; + let genesis_input = GenesisInput::new(&chain_genesis_config)?; let mut chain_contracts_config = chain_config.get_contracts_config()?; // Fund gateway's governor (chain_config.get_wallets_config()?.governor) @@ -521,7 +528,7 @@ async fn no_governance_stage_3( init_args.forge_args.clone(), ecosystem_config, &chain_config, - &chain_genesis_config, + &genesis_input, &ecosystem_config.get_initial_deployment_config().unwrap(), init_args.l1_rpc_url.clone(), ) @@ -587,7 +594,7 @@ async fn no_governance_stage_3( init_args.forge_args.clone(), ecosystem_config, &chain_config, - &chain_genesis_config, + &genesis_input, &ecosystem_config.get_initial_deployment_config().unwrap(), init_args.l1_rpc_url.clone(), ) diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/mod.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/mod.rs index 19c2888edd0d..9e9277bb2084 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/mod.rs @@ -43,7 +43,7 @@ pub enum EcosystemCommands { pub(crate) async fn run(shell: &Shell, args: EcosystemCommands) -> anyhow::Result<()> { match args { - EcosystemCommands::Create(args) => create::run(args, shell), + EcosystemCommands::Create(args) => create::run(args, shell).await, EcosystemCommands::BuildTransactions(args) => build_transactions::run(args, shell).await, EcosystemCommands::Init(args) => init::run(args, shell).await, EcosystemCommands::ChangeDefaultChain(args) => change_default::run(args, shell), diff --git a/zkstack_cli/crates/zkstack/src/commands/explorer/init.rs b/zkstack_cli/crates/zkstack/src/commands/explorer/init.rs index 8bac0b84d982..d5c8b6f905f5 100644 --- a/zkstack_cli/crates/zkstack/src/commands/explorer/init.rs +++ b/zkstack_cli/crates/zkstack/src/commands/explorer/init.rs @@ -6,7 +6,7 @@ use zkstack_cli_common::{config::global_config, db, logger, Prompt}; use zkstack_cli_config::{ explorer::{ExplorerChainConfig, ExplorerConfig}, explorer_compose::{ExplorerBackendComposeConfig, ExplorerBackendConfig, ExplorerBackendPorts}, - traits::{ConfigWithL2RpcUrl, SaveConfig}, + traits::SaveConfig, ChainConfig, EcosystemConfig, }; @@ -41,14 +41,18 @@ pub(crate) async fn run(shell: &Shell) -> anyhow::Result<()> { // Initialize explorer database initialize_explorer_database(&backend_config.database_url).await?; // Create explorer backend docker compose file - let l2_rpc_url = chain_config.get_general_config()?.get_l2_rpc_url()?; + let l2_rpc_url = chain_config + .get_general_config() + .await? + .get("api.web3_json_rpc.http_url")?; let backend_compose_config = ExplorerBackendComposeConfig::new(chain_name, l2_rpc_url, &backend_config)?; let backend_compose_config_path = ExplorerBackendComposeConfig::get_config_path(&shell.current_dir(), chain_name); backend_compose_config.save(shell, &backend_compose_config_path)?; // Add chain to explorer.json - let explorer_chain_config = build_explorer_chain_config(&chain_config, &backend_config)?; + let explorer_chain_config = + build_explorer_chain_config(&chain_config, &backend_config).await?; explorer_config.add_chain_config(&explorer_chain_config); } // Save explorer config @@ -100,19 +104,15 @@ fn fill_database_values_with_prompt(config: &ChainConfig) -> db::DatabaseConfig db::DatabaseConfig::new(explorer_db_url, explorer_db_name) } -fn build_explorer_chain_config( +async fn build_explorer_chain_config( chain_config: &ChainConfig, backend_config: &ExplorerBackendConfig, ) -> anyhow::Result { - let general_config = chain_config.get_general_config()?; + let general_config = chain_config.get_general_config().await?; // Get L2 RPC URL from general config - let l2_rpc_url = general_config.get_l2_rpc_url()?; + let l2_rpc_url = general_config.get("api.web3_json_rpc.http_url")?; // Get Verification API URL from general config - let verification_api_port = general_config - .contract_verifier - .as_ref() - .map(|verifier| verifier.port) - .context("verifier.port")?; + let verification_api_port = general_config.get::("contract_verifier.port")?; let verification_api_url = format!("http://127.0.0.1:{verification_api_port}"); // Build API URL let api_port = backend_config.ports.api_http_port; @@ -123,7 +123,7 @@ fn build_explorer_chain_config( name: chain_config.name.clone(), l2_network_name: chain_config.name.clone(), l2_chain_id: chain_config.chain_id.as_u64(), - rpc_url: l2_rpc_url.to_string(), + rpc_url: l2_rpc_url, api_url: api_url.to_string(), base_token_address: L2_BASE_TOKEN_ADDRESS.to_string(), hostnames: Vec::new(), diff --git a/zkstack_cli/crates/zkstack/src/commands/external_node/build.rs b/zkstack_cli/crates/zkstack/src/commands/external_node/build.rs index 8a4c4befe8db..581f08565162 100644 --- a/zkstack_cli/crates/zkstack/src/commands/external_node/build.rs +++ b/zkstack_cli/crates/zkstack/src/commands/external_node/build.rs @@ -10,7 +10,7 @@ pub(crate) async fn build(shell: &Shell) -> anyhow::Result<()> { let chain = ecosystem .load_current_chain() .context(MSG_CHAIN_NOT_FOUND_ERR)?; - let _dir_guard = shell.push_dir(&chain.link_to_code); + let _dir_guard = shell.push_dir(chain.link_to_code.join("core")); logger::info(MSG_BUILDING_EN); diff --git a/zkstack_cli/crates/zkstack/src/commands/external_node/init.rs b/zkstack_cli/crates/zkstack/src/commands/external_node/init.rs index 526e9fd4bc5f..3e4dfb179200 100644 --- a/zkstack_cli/crates/zkstack/src/commands/external_node/init.rs +++ b/zkstack_cli/crates/zkstack/src/commands/external_node/init.rs @@ -4,16 +4,13 @@ use zkstack_cli_common::{ db::{drop_db_if_exists, init_db, migrate_db, DatabaseConfig}, spinner::Spinner, }; -use zkstack_cli_config::{ - traits::ReadConfigWithBasePath, ChainConfig, EcosystemConfig, SecretsConfig, -}; +use zkstack_cli_config::{raw::RawConfig, ChainConfig, EcosystemConfig, SECRETS_FILE}; use crate::{ consts::SERVER_MIGRATIONS, messages::{ - MSG_CHAIN_NOT_INITIALIZED, MSG_DATABASE_MUST_BE_PRESENTED, - MSG_EXTERNAL_NODE_CONFIG_NOT_INITIALIZED, MSG_FAILED_TO_DROP_SERVER_DATABASE_ERR, - MSG_INITIALIZING_DATABASES_SPINNER, + MSG_CHAIN_NOT_INITIALIZED, MSG_EXTERNAL_NODE_CONFIG_NOT_INITIALIZED, + MSG_FAILED_TO_DROP_SERVER_DATABASE_ERR, MSG_INITIALIZING_DATABASES_SPINNER, }, utils::rocks_db::{recreate_rocksdb_dirs, RocksDBDirOption}, }; @@ -30,21 +27,13 @@ pub async fn run(shell: &Shell) -> anyhow::Result<()> { pub async fn init(shell: &Shell, chain_config: &ChainConfig) -> anyhow::Result<()> { let spin = Spinner::new(MSG_INITIALIZING_DATABASES_SPINNER); - let secrets = SecretsConfig::read_with_base_path( - shell, - chain_config - .external_node_config_path - .clone() - .context(MSG_EXTERNAL_NODE_CONFIG_NOT_INITIALIZED)?, - )?; - let db_config = DatabaseConfig::from_url( - secrets - .database - .as_ref() - .context(MSG_DATABASE_MUST_BE_PRESENTED)? - .master_url()? - .expose_url(), - )?; + let secrets_path = chain_config + .external_node_config_path + .as_ref() + .context(MSG_EXTERNAL_NODE_CONFIG_NOT_INITIALIZED)? + .join(SECRETS_FILE); + let secrets = RawConfig::read(shell, secrets_path).await?; + let db_config = DatabaseConfig::from_url(&secrets.get("database.server_url")?)?; drop_db_if_exists(&db_config) .await .context(MSG_FAILED_TO_DROP_SERVER_DATABASE_ERR)?; diff --git a/zkstack_cli/crates/zkstack/src/commands/external_node/mod.rs b/zkstack_cli/crates/zkstack/src/commands/external_node/mod.rs index 7bd366d5871c..28dc29dcf5eb 100644 --- a/zkstack_cli/crates/zkstack/src/commands/external_node/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/external_node/mod.rs @@ -28,7 +28,7 @@ pub enum ExternalNodeCommands { pub async fn run(shell: &Shell, commands: ExternalNodeCommands) -> anyhow::Result<()> { match commands { - ExternalNodeCommands::Configs(args) => prepare_configs::run(shell, args), + ExternalNodeCommands::Configs(args) => prepare_configs::run(shell, args).await, ExternalNodeCommands::Init => init::run(shell).await, ExternalNodeCommands::Build => build::build(shell).await, ExternalNodeCommands::Run(args) => run::run(shell, args).await, diff --git a/zkstack_cli/crates/zkstack/src/commands/external_node/prepare_configs.rs b/zkstack_cli/crates/zkstack/src/commands/external_node/prepare_configs.rs index ae36c1c9a1f4..9f0cd6bfbc8e 100644 --- a/zkstack_cli/crates/zkstack/src/commands/external_node/prepare_configs.rs +++ b/zkstack_cli/crates/zkstack/src/commands/external_node/prepare_configs.rs @@ -1,37 +1,30 @@ -use std::{collections::BTreeMap, path::Path, str::FromStr}; +use std::path::Path; use anyhow::Context; use xshell::Shell; use zkstack_cli_common::logger; use zkstack_cli_config::{ - external_node::ENConfig, - set_rocks_db_config, - traits::{FileConfigWithDefaultName, SaveConfigWithBasePath}, - ChainConfig, EcosystemConfig, GeneralConfig, SecretsConfig, -}; -use zksync_basic_types::url::SensitiveUrl; -use zksync_config::configs::{ - consensus::{ConsensusConfig, ConsensusSecrets, NodeSecretKey, Secret}, - DatabaseSecrets, L1Secrets, + raw::{PatchedConfig, RawConfig}, + set_rocks_db_config, ChainConfig, EcosystemConfig, CONSENSUS_CONFIG_FILE, EN_CONFIG_FILE, + GENERAL_FILE, SECRETS_FILE, }; +use zksync_basic_types::{L1ChainId, L2ChainId}; use zksync_consensus_crypto::TextFmt; use zksync_consensus_roles as roles; use crate::{ commands::external_node::args::prepare_configs::{PrepareConfigArgs, PrepareConfigFinal}, messages::{ - msg_preparing_en_config_is_done, MSG_CHAIN_NOT_INITIALIZED, - MSG_CONSENSUS_CONFIG_MISSING_ERR, MSG_CONSENSUS_SECRETS_MISSING_ERR, - MSG_CONSENSUS_SECRETS_NODE_KEY_MISSING_ERR, MSG_PREPARING_EN_CONFIGS, + msg_preparing_en_config_is_done, MSG_CHAIN_NOT_INITIALIZED, MSG_PREPARING_EN_CONFIGS, }, utils::{ - consensus::node_public_key, + consensus::{node_public_key, KeyAndAddress}, ports::EcosystemPortsScanner, rocks_db::{recreate_rocksdb_dirs, RocksDBDirOption}, }, }; -pub fn run(shell: &Shell, args: PrepareConfigArgs) -> anyhow::Result<()> { +pub async fn run(shell: &Shell, args: PrepareConfigArgs) -> anyhow::Result<()> { logger::info(MSG_PREPARING_EN_CONFIGS); let ecosystem_config = EcosystemConfig::from_file(shell)?; let mut chain_config = ecosystem_config @@ -44,104 +37,86 @@ pub fn run(shell: &Shell, args: PrepareConfigArgs) -> anyhow::Result<()> { .unwrap_or_else(|| chain_config.configs.join("external_node")); shell.create_dir(&external_node_config_path)?; chain_config.external_node_config_path = Some(external_node_config_path.clone()); - prepare_configs(shell, &chain_config, &external_node_config_path, args)?; + prepare_configs(shell, &chain_config, &external_node_config_path, args).await?; let chain_path = ecosystem_config.chains.join(&chain_config.name); chain_config.save_with_base_path(shell, chain_path)?; logger::info(msg_preparing_en_config_is_done(&external_node_config_path)); Ok(()) } -fn prepare_configs( +async fn prepare_configs( shell: &Shell, config: &ChainConfig, en_configs_path: &Path, args: PrepareConfigFinal, ) -> anyhow::Result<()> { let mut ports = EcosystemPortsScanner::scan(shell)?; - let genesis = config.get_genesis_config()?; - let general = config.get_general_config()?; + let genesis = config.get_genesis_config().await?; + let general = config.get_general_config().await?; let gateway = config.get_gateway_chain_config().ok(); - let en_config = ENConfig { - l2_chain_id: genesis.l2_chain_id, - l1_chain_id: genesis.l1_chain_id, - l1_batch_commit_data_generator_mode: genesis.l1_batch_commit_data_generator_mode, - main_node_url: SensitiveUrl::from_str( - &general - .api_config - .as_ref() - .context("api_config")? - .web3_json_rpc - .http_url, - )?, - main_node_rate_limit_rps: None, - bridge_addresses_refresh_interval_sec: None, - gateway_chain_id: gateway.map(|g| g.gateway_chain_id), - }; - let mut general_en = general.clone(); - general_en.consensus_config = None; + let l2_rpc_port = general.get::("api.web3_json_rpc.http_port")?; - let main_node_consensus_config = general - .consensus_config - .context(MSG_CONSENSUS_CONFIG_MISSING_ERR)?; - let mut en_consensus_config = main_node_consensus_config.clone(); + let mut en_config = PatchedConfig::empty(shell, en_configs_path.join(EN_CONFIG_FILE)); + en_config.insert( + "l2_chain_id", + genesis.get::("l2_chain_id")?.as_u64(), + )?; + en_config.insert("l1_chain_id", genesis.get::("l1_chain_id")?.0)?; + en_config.insert_yaml( + "l1_batch_commit_data_generator_mode", + genesis.get::("l1_batch_commit_data_generator_mode")?, + )?; + en_config.insert("main_node_url", format!("http://127.0.0.1:{l2_rpc_port}"))?; + if let Some(gateway) = &gateway { + en_config.insert_yaml("gateway_chain_id", gateway.gateway_chain_id)?; + } + en_config.save().await?; - let mut gossip_static_outbound = BTreeMap::new(); + // Copy and modify the general config + let general_config_path = en_configs_path.join(GENERAL_FILE); + shell.copy_file(config.path_to_general_config(), &general_config_path)?; + let mut general_en = RawConfig::read(shell, general_config_path.clone()) + .await? + .patched(); + let main_node_public_addr: String = general_en.base().get("consensus.public_addr")?; + let raw_consensus = general_en.base().get("consensus")?; + general_en.remove("consensus"); + + // Copy and modify the consensus config + let mut en_consensus_config = + PatchedConfig::empty(shell, en_configs_path.join(CONSENSUS_CONFIG_FILE)); + en_consensus_config.extend(raw_consensus); let main_node_public_key = node_public_key( &config - .get_secrets_config()? - .consensus - .context(MSG_CONSENSUS_SECRETS_MISSING_ERR)?, - )? - .context(MSG_CONSENSUS_SECRETS_NODE_KEY_MISSING_ERR)?; - gossip_static_outbound.insert(main_node_public_key, main_node_consensus_config.public_addr); - en_consensus_config.gossip_static_outbound = gossip_static_outbound; + .get_secrets_config() + .await? + .get::("consensus.node_key")?, + )?; + let gossip_static_outbound = [KeyAndAddress { + key: main_node_public_key, + addr: main_node_public_addr, + }]; + en_consensus_config.insert_yaml("gossip_static_outbound", gossip_static_outbound)?; + en_consensus_config.save().await?; // Set secrets config + let mut secrets = PatchedConfig::empty(shell, en_configs_path.join(SECRETS_FILE)); let node_key = roles::node::SecretKey::generate().encode(); - let consensus_secrets = ConsensusSecrets { - validator_key: None, - attester_key: None, - node_key: Some(NodeSecretKey(Secret::new(node_key))), - }; - - let gateway_rpc_url = if let Some(url) = args.gateway_rpc_url { - Some(SensitiveUrl::from_str(&url).context("gateway_url")?) - } else { - None - }; - let secrets = SecretsConfig { - consensus: Some(consensus_secrets), - database: Some(DatabaseSecrets { - server_url: Some(args.db.full_url().into()), - prover_url: None, - server_replica_url: None, - }), - l1: Some(L1Secrets { - l1_rpc_url: SensitiveUrl::from_str(&args.l1_rpc_url).context("l1_rpc_url")?, - gateway_rpc_url, - }), - data_availability: None, - }; + secrets.insert("consensus.node_key", node_key)?; + secrets.insert("database.server_url", args.db.full_url().to_string())?; + secrets.insert("l1.l1_rpc_url", args.l1_rpc_url)?; + if let Some(url) = args.gateway_rpc_url { + secrets.insert("l1.gateway_rpc_url", url)?; + } + secrets.save().await?; let dirs = recreate_rocksdb_dirs(shell, &config.rocks_db_path, RocksDBDirOption::ExternalNode)?; set_rocks_db_config(&mut general_en, dirs)?; - - general_en.save_with_base_path(shell, en_configs_path)?; - en_config.save_with_base_path(shell, en_configs_path)?; - en_consensus_config.save_with_base_path(shell, en_configs_path)?; - secrets.save_with_base_path(shell, en_configs_path)?; + general_en.save().await?; let offset = 0; // This is zero because general_en ports already have a chain offset - ports.allocate_ports_in_yaml( - shell, - &GeneralConfig::get_path_with_base_path(en_configs_path), - offset, - )?; - ports.allocate_ports_in_yaml( - shell, - &ConsensusConfig::get_path_with_base_path(en_configs_path), - offset, - )?; + ports.allocate_ports_in_yaml(shell, &general_config_path, offset)?; + ports.allocate_ports_in_yaml(shell, &en_configs_path.join(CONSENSUS_CONFIG_FILE), offset)?; Ok(()) } diff --git a/zkstack_cli/crates/zkstack/src/commands/external_node/wait.rs b/zkstack_cli/crates/zkstack/src/commands/external_node/wait.rs index b645314dc9c2..40adcb3f73a0 100644 --- a/zkstack_cli/crates/zkstack/src/commands/external_node/wait.rs +++ b/zkstack_cli/crates/zkstack/src/commands/external_node/wait.rs @@ -1,8 +1,7 @@ use anyhow::Context as _; use xshell::Shell; use zkstack_cli_common::{config::global_config, logger}; -use zkstack_cli_config::{traits::ReadConfigWithBasePath, EcosystemConfig}; -use zksync_config::configs::GeneralConfig; +use zkstack_cli_config::{raw::RawConfig, EcosystemConfig, GENERAL_FILE}; use crate::{ commands::args::WaitArgs, @@ -20,13 +19,8 @@ pub async fn wait(shell: &Shell, args: WaitArgs) -> anyhow::Result<()> { .external_node_config_path .clone() .context("External node is not initialized")?; - let general_config = GeneralConfig::read_with_base_path(shell, &en_path)?; - let health_check_port = general_config - .api_config - .as_ref() - .context("no API config")? - .healthcheck - .port; + let general_config = RawConfig::read(shell, en_path.join(GENERAL_FILE)).await?; + let health_check_port = general_config.get("api.healthcheck.port")?; logger::info(MSG_WAITING_FOR_EN); args.poll_health_check(health_check_port, verbose).await?; diff --git a/zkstack_cli/crates/zkstack/src/commands/portal.rs b/zkstack_cli/crates/zkstack/src/commands/portal.rs index d534498aaacd..15043abd509f 100644 --- a/zkstack_cli/crates/zkstack/src/commands/portal.rs +++ b/zkstack_cli/crates/zkstack/src/commands/portal.rs @@ -5,9 +5,7 @@ use ethers::types::Address; use xshell::Shell; use zkstack_cli_common::{config::global_config, docker, ethereum, logger}; use zkstack_cli_config::{ - portal::*, - traits::{ConfigWithL2RpcUrl, SaveConfig}, - AppsEcosystemConfig, ChainConfig, EcosystemConfig, + portal::*, traits::SaveConfig, AppsEcosystemConfig, ChainConfig, EcosystemConfig, }; use zkstack_cli_types::{BaseToken, TokenInfo}; @@ -24,14 +22,13 @@ async fn build_portal_chain_config( chain_config: &ChainConfig, ) -> anyhow::Result { // Get L2 RPC URL from general config - let l2_rpc_url = chain_config.get_general_config()?.get_l2_rpc_url()?; - // Get L1 RPC URL from secrects config - let secrets_config = chain_config.get_secrets_config()?; - let l1_rpc_url = secrets_config - .l1 - .as_ref() - .map(|l1| l1.l1_rpc_url.expose_str()) - .context("l1")?; + let l2_rpc_url = chain_config + .get_general_config() + .await? + .get("api.web3_json_rpc.http_url")?; + // Get L1 RPC URL from secrets config + let secrets_config = chain_config.get_secrets_config().await?; + let l1_rpc_url = secrets_config.get::("l1.l1_rpc_url")?; // Build L1 network config let l1_network = Some(L1NetworkConfig { id: chain_config.l1_network.chain_id(), @@ -40,10 +37,10 @@ async fn build_portal_chain_config( native_currency: TokenInfo::eth(), rpc_urls: RpcUrls { default: RpcUrlConfig { - http: vec![l1_rpc_url.to_string()], + http: vec![l1_rpc_url.clone()], }, public: RpcUrlConfig { - http: vec![l1_rpc_url.to_string()], + http: vec![l1_rpc_url.clone()], }, }, }); @@ -53,8 +50,7 @@ async fn build_portal_chain_config( } else { ( format!("{:?}", chain_config.base_token.address), - ethereum::get_token_info(chain_config.base_token.address, l1_rpc_url.to_string()) - .await?, + ethereum::get_token_info(chain_config.base_token.address, l1_rpc_url).await?, ) }; let tokens = vec![TokenConfig { @@ -70,7 +66,7 @@ async fn build_portal_chain_config( id: chain_config.chain_id.as_u64(), key: chain_config.name.clone(), name: chain_config.name.clone(), - rpc_url: l2_rpc_url.to_string(), + rpc_url: l2_rpc_url, l1_network, public_l1_network_id: None, block_explorer_url: None, diff --git a/zkstack_cli/crates/zkstack/src/commands/prover/args/compressor_keys.rs b/zkstack_cli/crates/zkstack/src/commands/prover/args/compressor_keys.rs index 8b7bfb0fc543..9c9445bc3718 100644 --- a/zkstack_cli/crates/zkstack/src/commands/prover/args/compressor_keys.rs +++ b/zkstack_cli/crates/zkstack/src/commands/prover/args/compressor_keys.rs @@ -1,5 +1,6 @@ -use clap::{Parser, ValueEnum}; -use strum::EnumIter; +use std::path::{Path, PathBuf}; + +use clap::Parser; use zkstack_cli_common::Prompt; use crate::messages::MSG_SETUP_COMPRESSOR_KEY_PATH_PROMPT; @@ -7,51 +8,17 @@ use crate::messages::MSG_SETUP_COMPRESSOR_KEY_PATH_PROMPT; #[derive(Debug, Clone, Parser, Default)] pub struct CompressorKeysArgs { #[clap(long)] - pub plonk_path: Option, - #[clap(long)] - pub fflonk_path: Option, - #[clap(long, default_value = "plonk")] - pub compressor_type: CompressorType, -} - -#[derive(Debug, Clone, ValueEnum, EnumIter, strum::Display, PartialEq, Eq, Default)] -pub enum CompressorType { - Fflonk, - #[default] - Plonk, - All, + pub path: Option, } impl CompressorKeysArgs { - pub fn fill_values_with_prompt( - self, - default_plonk_path: &str, - default_fflonk_path: &str, - ) -> CompressorKeysArgs { - let plonk_path = if self.compressor_type != CompressorType::Fflonk { - Some(self.plonk_path.unwrap_or_else(|| { - Prompt::new(MSG_SETUP_COMPRESSOR_KEY_PATH_PROMPT) - .default(default_plonk_path) - .ask() - })) - } else { - None - }; - - let fflonk_path = if self.compressor_type != CompressorType::Plonk { - Some(self.fflonk_path.unwrap_or_else(|| { - Prompt::new(MSG_SETUP_COMPRESSOR_KEY_PATH_PROMPT) - .default(default_fflonk_path) - .ask() - })) - } else { - None - }; + pub fn fill_values_with_prompt(self, default_path: &Path) -> CompressorKeysArgs { + let path = self.path.unwrap_or_else(|| { + Prompt::new(MSG_SETUP_COMPRESSOR_KEY_PATH_PROMPT) + .default(default_path.to_str().expect("non-UTF8 path")) + .ask() + }); - CompressorKeysArgs { - plonk_path, - fflonk_path, - ..self - } + CompressorKeysArgs { path: Some(path) } } } diff --git a/zkstack_cli/crates/zkstack/src/commands/prover/args/init.rs b/zkstack_cli/crates/zkstack/src/commands/prover/args/init.rs index afe57a8f5eb4..b0eabd4925ea 100644 --- a/zkstack_cli/crates/zkstack/src/commands/prover/args/init.rs +++ b/zkstack_cli/crates/zkstack/src/commands/prover/args/init.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use clap::{Parser, ValueEnum}; use serde::{Deserialize, Serialize}; use slugify_rs::slugify; @@ -6,7 +8,6 @@ use url::Url; use xshell::Shell; use zkstack_cli_common::{db::DatabaseConfig, logger, Prompt, PromptConfirm, PromptSelect}; use zkstack_cli_config::ChainConfig; -use zksync_config::configs::fri_prover::CloudConnectionMode; use super::{ compressor_keys::CompressorKeysArgs, init_bellman_cuda::InitBellmanCudaArgs, @@ -92,24 +93,14 @@ enum ProofStoreConfig { GCS, } -#[derive( - Debug, Clone, ValueEnum, EnumIter, strum::Display, PartialEq, Eq, Deserialize, Serialize, -)] +#[derive(Debug, Clone, ValueEnum, EnumIter, strum::Display, PartialEq, Eq, Serialize)] #[allow(clippy::upper_case_acronyms)] -enum InternalCloudConnectionMode { +pub enum InternalCloudConnectionMode { GCP, + #[serde(rename = "LOCAL")] // match name in file-based configs Local, } -impl From for CloudConnectionMode { - fn from(cloud_type: InternalCloudConnectionMode) -> Self { - match cloud_type { - InternalCloudConnectionMode::GCP => CloudConnectionMode::GCP, - InternalCloudConnectionMode::Local => CloudConnectionMode::Local, - } - } -} - #[derive(Clone, Debug, Serialize, Deserialize, Parser, Default)] pub struct ProofStorageGCSTmp { #[clap(long)] @@ -194,7 +185,7 @@ pub struct ProverInitArgsFinal { pub compressor_key_args: Option, pub setup_keys: Option, pub bellman_cuda_config: Option, - pub cloud_type: CloudConnectionMode, + pub cloud_type: InternalCloudConnectionMode, pub database_config: Option, } @@ -202,16 +193,13 @@ impl ProverInitArgs { pub(crate) fn fill_values_with_prompt( &self, shell: &Shell, - default_plonk_key_path: &str, - default_fflonk_key_path: &str, + default_compressor_key_path: &Path, chain_config: &ChainConfig, ) -> anyhow::Result { let proof_store = self.fill_proof_storage_values_with_prompt(shell)?; let public_store = self.fill_public_storage_values_with_prompt(shell)?; - let compressor_key_args = self.fill_setup_compressor_key_values_with_prompt( - default_plonk_key_path, - default_fflonk_key_path, - ); + let compressor_key_args = + self.fill_setup_compressor_key_values_with_prompt(default_compressor_key_path); let bellman_cuda_config = self.fill_bellman_cuda_values_with_prompt(); let cloud_type = self.get_cloud_type_with_prompt(); let database_config = self.fill_database_values_with_prompt(chain_config); @@ -358,14 +346,11 @@ impl ProverInitArgs { fn fill_setup_compressor_key_values_with_prompt( &self, - default_plonk_path: &str, - default_fflonk_path: &str, + default_path: &Path, ) -> Option { if self.dev { return Some(CompressorKeysArgs { - plonk_path: Some(default_plonk_path.to_string()), - fflonk_path: Some(default_fflonk_path.to_string()), - ..self.compressor_keys_args.clone() + path: Some(default_path.to_owned()), }); } @@ -379,7 +364,7 @@ impl ProverInitArgs { Some( self.compressor_keys_args .clone() - .fill_values_with_prompt(default_plonk_path, default_fflonk_path), + .fill_values_with_prompt(default_path), ) } else { None @@ -518,20 +503,18 @@ impl ProverInitArgs { } } - fn get_cloud_type_with_prompt(&self) -> CloudConnectionMode { + fn get_cloud_type_with_prompt(&self) -> InternalCloudConnectionMode { if self.dev { - return CloudConnectionMode::Local; + return InternalCloudConnectionMode::Local; } - let cloud_type = self.cloud_type.clone().unwrap_or_else(|| { + self.cloud_type.clone().unwrap_or_else(|| { PromptSelect::new( MSG_CLOUD_TYPE_PROMPT, InternalCloudConnectionMode::iter().rev(), ) .ask() - }); - - cloud_type.into() + }) } fn fill_database_values_with_prompt( diff --git a/zkstack_cli/crates/zkstack/src/commands/prover/compressor_keys.rs b/zkstack_cli/crates/zkstack/src/commands/prover/compressor_keys.rs index 19ba634a4075..77bb45a1336d 100644 --- a/zkstack_cli/crates/zkstack/src/commands/prover/compressor_keys.rs +++ b/zkstack_cli/crates/zkstack/src/commands/prover/compressor_keys.rs @@ -1,12 +1,13 @@ +use std::path::{Path, PathBuf}; + use anyhow::Context; use xshell::Shell; use zkstack_cli_common::{logger, spinner::Spinner}; -use zkstack_cli_config::{get_link_to_prover, EcosystemConfig, GeneralConfig}; +use zkstack_cli_config::{get_link_to_prover, raw::PatchedConfig, EcosystemConfig}; -use super::args::compressor_keys::{CompressorKeysArgs, CompressorType}; +use super::args::compressor_keys::CompressorKeysArgs; use crate::messages::{ - MSG_CHAIN_NOT_FOUND_ERR, MSG_DOWNLOADING_SETUP_COMPRESSOR_KEY_SPINNER, - MSG_PROOF_COMPRESSOR_CONFIG_NOT_FOUND_ERR, MSG_SETUP_KEY_PATH_ERROR, + MSG_CHAIN_NOT_FOUND_ERR, MSG_DOWNLOADING_SETUP_COMPRESSOR_KEY_SPINNER, MSG_SETUP_KEY_PATH_ERROR, }; pub(crate) async fn run(shell: &Shell, args: CompressorKeysArgs) -> anyhow::Result<()> { @@ -14,77 +15,32 @@ pub(crate) async fn run(shell: &Shell, args: CompressorKeysArgs) -> anyhow::Resu let chain_config = ecosystem_config .load_current_chain() .context(MSG_CHAIN_NOT_FOUND_ERR)?; - let mut general_config = chain_config.get_general_config()?; - - let default_plonk_path = get_default_plonk_compressor_keys_path(&ecosystem_config)?; - let default_fflonk_path = get_default_fflonk_compressor_keys_path(&ecosystem_config)?; - let args = args.fill_values_with_prompt(&default_plonk_path, &default_fflonk_path); - - match args.compressor_type { - CompressorType::Fflonk => { - let path = args.clone().fflonk_path.context(MSG_SETUP_KEY_PATH_ERROR)?; + let mut general_config = chain_config.get_general_config().await?.patched(); - download_compressor_key(shell, &mut general_config, CompressorType::Fflonk, &path)?; - } - CompressorType::Plonk => { - let path = args.plonk_path.context(MSG_SETUP_KEY_PATH_ERROR)?; + let default_path = get_default_compressor_keys_path(&ecosystem_config)?; + let args = args.fill_values_with_prompt(&default_path); - download_compressor_key(shell, &mut general_config, CompressorType::Plonk, &path)?; - } - CompressorType::All => { - let plonk_path = args.clone().plonk_path.context(MSG_SETUP_KEY_PATH_ERROR)?; - let fflonk_path = args.clone().fflonk_path.context(MSG_SETUP_KEY_PATH_ERROR)?; + let path = args.path.context(MSG_SETUP_KEY_PATH_ERROR)?; - download_compressor_key( - shell, - &mut general_config, - CompressorType::Fflonk, - &fflonk_path, - )?; - download_compressor_key( - shell, - &mut general_config, - CompressorType::Plonk, - &plonk_path, - )?; - } - } - - chain_config.save_general_config(&general_config)?; + download_compressor_key(shell, &mut general_config, &path)?; + general_config.save().await?; Ok(()) } pub(crate) fn download_compressor_key( shell: &Shell, - general_config: &mut GeneralConfig, - r#type: CompressorType, - path: &str, + general_config: &mut PatchedConfig, + path: &Path, ) -> anyhow::Result<()> { let spinner = Spinner::new(MSG_DOWNLOADING_SETUP_COMPRESSOR_KEY_SPINNER); - let mut compressor_config: zksync_config::configs::FriProofCompressorConfig = general_config - .proof_compressor_config - .as_ref() - .expect(MSG_PROOF_COMPRESSOR_CONFIG_NOT_FOUND_ERR) - .clone(); - - let url = match r#type { - CompressorType::Fflonk => { - compressor_config.universal_fflonk_setup_path = path.to_string(); - general_config.proof_compressor_config = Some(compressor_config.clone()); - compressor_config.universal_fflonk_setup_download_url - } - CompressorType::Plonk => { - compressor_config.universal_setup_path = path.to_string(); - general_config.proof_compressor_config = Some(compressor_config.clone()); - compressor_config.universal_setup_download_url - } - _ => unreachable!("Invalid compressor type"), - }; - let path = std::path::Path::new(path); + general_config.insert_path("proof_compressor.universal_setup_path", path)?; - logger::info(format!("Downloading setup key by URL: {}", url)); + let url = general_config + .base() + .get::("proof_compressor.universal_setup_download_url")?; + logger::info(format!("Downloading setup key by URL: {url}")); let client = reqwest::blocking::Client::builder() .timeout(std::time::Duration::from_secs(600)) @@ -97,22 +53,9 @@ pub(crate) fn download_compressor_key( Ok(()) } -pub fn get_default_plonk_compressor_keys_path( +pub fn get_default_compressor_keys_path( ecosystem_config: &EcosystemConfig, -) -> anyhow::Result { +) -> anyhow::Result { let link_to_prover = get_link_to_prover(ecosystem_config); - let path = link_to_prover.join("keys/setup/setup_2^24.key"); - let string = path.to_str().unwrap(); - - Ok(String::from(string)) -} - -pub fn get_default_fflonk_compressor_keys_path( - ecosystem_config: &EcosystemConfig, -) -> anyhow::Result { - let link_to_prover = get_link_to_prover(ecosystem_config); - let path = link_to_prover.join("keys/setup/setup_fflonk_compact.key"); - let string = path.to_str().unwrap(); - - Ok(String::from(string)) + Ok(link_to_prover.join("keys/setup/setup_compact.key")) } diff --git a/zkstack_cli/crates/zkstack/src/commands/prover/init.rs b/zkstack_cli/crates/zkstack/src/commands/prover/init.rs index b318f4924ec3..edfdc31e6186 100644 --- a/zkstack_cli/crates/zkstack/src/commands/prover/init.rs +++ b/zkstack_cli/crates/zkstack/src/commands/prover/init.rs @@ -10,113 +10,75 @@ use zkstack_cli_common::{ spinner::Spinner, }; use zkstack_cli_config::{ - copy_configs, get_link_to_prover, set_prover_database, traits::SaveConfigWithBasePath, - EcosystemConfig, + copy_configs, get_link_to_prover, raw::PatchedConfig, set_prover_database, EcosystemConfig, }; use zksync_config::{configs::object_store::ObjectStoreMode, ObjectStoreConfig}; use super::{ - args::init::{ProofStorageConfig, ProverInitArgs}, - compressor_keys::download_compressor_key, + args::init::{ProofStorageConfig, ProofStorageFileBacked, ProverInitArgs}, + compressor_keys::{download_compressor_key, get_default_compressor_keys_path}, gcs::create_gcs_bucket, init_bellman_cuda::run as init_bellman_cuda, setup_keys, }; use crate::{ - commands::prover::{ - args::{compressor_keys::CompressorType, init::ProofStorageFileBacked}, - compressor_keys::{ - get_default_fflonk_compressor_keys_path, get_default_plonk_compressor_keys_path, - }, - }, consts::{PROVER_MIGRATIONS, PROVER_STORE_MAX_RETRIES}, messages::{ MSG_CHAIN_NOT_FOUND_ERR, MSG_FAILED_TO_DROP_PROVER_DATABASE_ERR, - MSG_GENERAL_CONFIG_NOT_FOUND_ERR, MSG_INITIALIZING_DATABASES_SPINNER, - MSG_INITIALIZING_PROVER_DATABASE, MSG_PROVER_CONFIG_NOT_FOUND_ERR, MSG_PROVER_INITIALIZED, - MSG_SETUP_KEY_PATH_ERROR, + MSG_INITIALIZING_DATABASES_SPINNER, MSG_INITIALIZING_PROVER_DATABASE, + MSG_PROVER_INITIALIZED, MSG_SETUP_KEY_PATH_ERROR, }, }; pub(crate) async fn run(args: ProverInitArgs, shell: &Shell) -> anyhow::Result<()> { let ecosystem_config = EcosystemConfig::from_file(shell)?; - let default_plonk_key_path = get_default_plonk_compressor_keys_path(&ecosystem_config)?; - let default_fflonk_key_path = get_default_fflonk_compressor_keys_path(&ecosystem_config)?; + let default_compressor_key_path = get_default_compressor_keys_path(&ecosystem_config)?; let chain_config = ecosystem_config .load_current_chain() .context(MSG_CHAIN_NOT_FOUND_ERR)?; - let args = args.fill_values_with_prompt( - shell, - &default_plonk_key_path, - &default_fflonk_key_path, - &chain_config, - )?; + let args = args.fill_values_with_prompt(shell, &default_compressor_key_path, &chain_config)?; - if chain_config.get_general_config().is_err() || chain_config.get_secrets_config().is_err() { + if chain_config.get_general_config().await.is_err() + || chain_config.get_secrets_config().await.is_err() + { copy_configs(shell, &ecosystem_config.link_to_code, &chain_config.configs)?; } - let mut general_config = chain_config - .get_general_config() - .context(MSG_GENERAL_CONFIG_NOT_FOUND_ERR)?; + let mut general_config = chain_config.get_general_config().await?.patched(); - let proof_object_store_config = get_object_store_config(shell, Some(args.proof_store))?; + let proof_object_store_config = + get_object_store_config(shell, Some(args.proof_store))?.unwrap(); let public_object_store_config = get_object_store_config(shell, args.public_store)?; if let Some(args) = args.compressor_key_args { - match args.compressor_type { - CompressorType::Fflonk => { - let path = args.clone().fflonk_path.context(MSG_SETUP_KEY_PATH_ERROR)?; - - download_compressor_key(shell, &mut general_config, CompressorType::Fflonk, &path)?; - } - CompressorType::Plonk => { - let path = args.plonk_path.context(MSG_SETUP_KEY_PATH_ERROR)?; - - download_compressor_key(shell, &mut general_config, CompressorType::Plonk, &path)?; - } - CompressorType::All => { - let fflonk_path = args.clone().fflonk_path.context(MSG_SETUP_KEY_PATH_ERROR)?; - let plonk_path = args.clone().plonk_path.context(MSG_SETUP_KEY_PATH_ERROR)?; - - download_compressor_key( - shell, - &mut general_config, - CompressorType::Fflonk, - &fflonk_path, - )?; - download_compressor_key( - shell, - &mut general_config, - CompressorType::Plonk, - &plonk_path, - )?; - } - } + let path = args.path.context(MSG_SETUP_KEY_PATH_ERROR)?; + + download_compressor_key(shell, &mut general_config, &path)?; } if let Some(args) = args.setup_keys { setup_keys::run(args, shell).await?; } - let mut prover_config = general_config - .prover_config - .expect(MSG_PROVER_CONFIG_NOT_FOUND_ERR); - prover_config - .prover_object_store - .clone_from(&proof_object_store_config); + set_object_store( + &mut general_config, + "prover.prover_object_store", + &proof_object_store_config, + )?; if let Some(public_object_store_config) = public_object_store_config { - prover_config.shall_save_to_public_bucket = true; - prover_config.public_object_store = Some(public_object_store_config); + general_config.insert("prover.shall_save_to_public_bucket", true)?; + set_object_store( + &mut general_config, + "prover.public_object_store", + &public_object_store_config, + )?; } else { - prover_config.shall_save_to_public_bucket = false; + general_config.insert("prover.shall_save_to_public_bucket", false)?; } - prover_config.cloud_type = args.cloud_type; - general_config.prover_config = Some(prover_config); - - chain_config.save_general_config(&general_config)?; + general_config.insert_yaml("prover.cloud_type", args.cloud_type)?; + general_config.save().await?; if let Some(args) = args.bellman_cuda_config { init_bellman_cuda(shell, args).await?; @@ -125,9 +87,9 @@ pub(crate) async fn run(args: ProverInitArgs, shell: &Shell) -> anyhow::Result<( if let Some(prover_db) = &args.database_config { let spinner = Spinner::new(MSG_INITIALIZING_DATABASES_SPINNER); - let mut secrets = chain_config.get_secrets_config()?; + let mut secrets = chain_config.get_secrets_config().await?.patched(); set_prover_database(&mut secrets, &prover_db.database_config)?; - secrets.save_with_base_path(shell, &chain_config.configs)?; + secrets.save().await?; initialize_prover_database( shell, &prover_db.database_config, @@ -170,6 +132,50 @@ fn get_object_store_config( Ok(object_store) } +fn set_object_store( + patch: &mut PatchedConfig, + prefix: &str, + config: &ObjectStoreConfig, +) -> anyhow::Result<()> { + patch.insert(&format!("{prefix}.max_retries"), config.max_retries)?; + match &config.mode { + ObjectStoreMode::FileBacked { + file_backed_base_path, + } => { + patch.insert_yaml( + &format!("{prefix}.file_backed.file_backed_base_path"), + file_backed_base_path, + )?; + } + ObjectStoreMode::GCS { bucket_base_url } => { + patch.insert( + &format!("{prefix}.gcs.bucket_base_url"), + bucket_base_url.clone(), + )?; + } + ObjectStoreMode::GCSWithCredentialFile { + bucket_base_url, + gcs_credential_file_path, + } => { + patch.insert( + &format!("{prefix}.gcs_with_credential_file.bucket_base_url"), + bucket_base_url.clone(), + )?; + patch.insert( + &format!("{prefix}.gcs_with_credential_file.gcs_credential_file_path"), + gcs_credential_file_path.clone(), + )?; + } + ObjectStoreMode::GCSAnonymousReadOnly { bucket_base_url } => { + patch.insert( + &format!("{prefix}.gcs_anonymous_read_only.bucket_base_url"), + bucket_base_url.clone(), + )?; + } + } + Ok(()) +} + async fn initialize_prover_database( shell: &Shell, prover_db_config: &DatabaseConfig, diff --git a/zkstack_cli/crates/zkstack/src/commands/prover/run.rs b/zkstack_cli/crates/zkstack/src/commands/prover/run.rs index 495c41ef8255..e7101d92ab6e 100644 --- a/zkstack_cli/crates/zkstack/src/commands/prover/run.rs +++ b/zkstack_cli/crates/zkstack/src/commands/prover/run.rs @@ -79,7 +79,7 @@ pub(crate) async fn run(args: ProverRunArgs, shell: &Shell) -> anyhow::Result<() if in_docker { let path_to_configs = chain.configs.clone(); let path_to_prover = get_link_to_prover(&ecosystem_config); - update_setup_data_path(&chain, "prover/data/keys".to_string())?; + update_setup_data_path(&chain, "prover/data/keys").await?; run_dockerized_component( shell, component.image_name(), @@ -93,7 +93,7 @@ pub(crate) async fn run(args: ProverRunArgs, shell: &Shell) -> anyhow::Result<() &path_to_ecosystem, )? } else { - update_setup_data_path(&chain, "data/keys".to_string())?; + update_setup_data_path(&chain, "data/keys").await?; run_binary_component( shell, component.binary_name(), @@ -151,13 +151,8 @@ fn run_binary_component( cmd.run().context(error) } -fn update_setup_data_path(chain: &ChainConfig, path: String) -> anyhow::Result<()> { - let mut general_config = chain.get_general_config()?; - general_config - .prover_config - .as_mut() - .expect("Prover config not found") - .setup_data_path = path; - chain.save_general_config(&general_config)?; - Ok(()) +async fn update_setup_data_path(chain: &ChainConfig, path: &str) -> anyhow::Result<()> { + let mut general_config = chain.get_general_config().await?.patched(); + general_config.insert_path("prover.setup_data_path", path.as_ref())?; + general_config.save().await } diff --git a/zkstack_cli/crates/zkstack/src/commands/server.rs b/zkstack_cli/crates/zkstack/src/commands/server.rs index 4088a888d534..11b10ecec594 100644 --- a/zkstack_cli/crates/zkstack/src/commands/server.rs +++ b/zkstack_cli/crates/zkstack/src/commands/server.rs @@ -8,7 +8,7 @@ use zkstack_cli_common::{ }; use zkstack_cli_config::{ traits::FileConfigWithDefaultName, ChainConfig, ContractsConfig, EcosystemConfig, - GeneralConfig, GenesisConfig, SecretsConfig, WalletsConfig, + WalletsConfig, GENERAL_FILE, GENESIS_FILE, SECRETS_FILE, }; use zksync_config::configs::gateway::GatewayChainConfig; @@ -35,7 +35,7 @@ pub async fn run(shell: &Shell, args: ServerArgs) -> anyhow::Result<()> { } fn build_server(chain_config: &ChainConfig, shell: &Shell) -> anyhow::Result<()> { - let _dir_guard = shell.push_dir(&chain_config.link_to_code); + let _dir_guard = shell.push_dir(chain_config.link_to_code.join("core")); logger::info(MSG_BUILDING_SERVER); @@ -78,10 +78,10 @@ fn run_server( .run( shell, mode, - GenesisConfig::get_path_with_base_path(&chain_config.configs), + chain_config.configs.join(GENESIS_FILE), WalletsConfig::get_path_with_base_path(&chain_config.configs), - GeneralConfig::get_path_with_base_path(&chain_config.configs), - SecretsConfig::get_path_with_base_path(&chain_config.configs), + chain_config.configs.join(GENERAL_FILE), + chain_config.configs.join(SECRETS_FILE), ContractsConfig::get_path_with_base_path(&chain_config.configs), gateway_contracts, vec![], @@ -93,13 +93,9 @@ async fn wait_for_server(args: WaitArgs, chain_config: &ChainConfig) -> anyhow:: let verbose = global_config().verbose; let health_check_port = chain_config - .get_general_config()? - .api_config - .as_ref() - .context("no API config")? - .healthcheck - .port; - + .get_general_config() + .await? + .get("api.healthcheck.port")?; logger::info(MSG_WAITING_FOR_SERVER); args.poll_health_check(health_check_port, verbose).await?; logger::info(msg_waiting_for_server_success(health_check_port)); diff --git a/zkstack_cli/crates/zkstack/src/commands/update.rs b/zkstack_cli/crates/zkstack/src/commands/update.rs index 0e1d385f8fef..095619b43f0e 100644 --- a/zkstack_cli/crates/zkstack/src/commands/update.rs +++ b/zkstack_cli/crates/zkstack/src/commands/update.rs @@ -1,6 +1,7 @@ use std::path::Path; -use anyhow::{Context, Ok}; +use anyhow::Context; +use url::Url; use xshell::Shell; use zkstack_cli_common::{ db::migrate_db, @@ -182,17 +183,14 @@ async fn update_chain( )?; } - let secrets = chain.get_secrets_config()?; - - if let Some(db) = secrets.database { - if let Some(url) = db.server_url { - let path_to_migration = chain.link_to_code.join(SERVER_MIGRATIONS); - migrate_db(shell, path_to_migration, url.expose_url()).await?; - } - if let Some(url) = db.prover_url { - let path_to_migration = chain.link_to_code.join(PROVER_MIGRATIONS); - migrate_db(shell, path_to_migration, url.expose_url()).await?; - } + let secrets = chain.get_secrets_config().await?; + if let Some(url) = secrets.get_opt::("database.server_url")? { + let path_to_migration = chain.link_to_code.join(SERVER_MIGRATIONS); + migrate_db(shell, path_to_migration, &url).await?; + } + if let Some(url) = secrets.get_opt::("database.prover_url")? { + let path_to_migration = chain.link_to_code.join(PROVER_MIGRATIONS); + migrate_db(shell, path_to_migration, &url).await?; } Ok(()) } diff --git a/zkstack_cli/crates/zkstack/src/external_node.rs b/zkstack_cli/crates/zkstack/src/external_node.rs index 21d4e0db5592..7cc4dcbe6d68 100644 --- a/zkstack_cli/crates/zkstack/src/external_node.rs +++ b/zkstack_cli/crates/zkstack/src/external_node.rs @@ -3,10 +3,8 @@ use std::path::PathBuf; use anyhow::Context; use xshell::Shell; use zkstack_cli_config::{ - external_node::ENConfig, traits::FileConfigWithDefaultName, ChainConfig, GeneralConfig, - SecretsConfig, + ChainConfig, CONSENSUS_CONFIG_FILE, EN_CONFIG_FILE, GENERAL_FILE, SECRETS_FILE, }; -use zksync_config::configs::consensus::ConsensusConfig; use crate::messages::MSG_FAILED_TO_RUN_SERVER_ERR; @@ -28,17 +26,17 @@ impl RunExternalNode { .external_node_config_path .clone() .context("External node is not initialized")?; - let general_config = GeneralConfig::get_path_with_base_path(&en_path); - let secrets = SecretsConfig::get_path_with_base_path(&en_path); - let enconfig = ENConfig::get_path_with_base_path(&en_path); - let consensus_config = ConsensusConfig::get_path_with_base_path(&en_path); + let general_config = en_path.join(GENERAL_FILE); + let secrets = en_path.join(SECRETS_FILE); + let en_config = en_path.join(EN_CONFIG_FILE); + let consensus_config = en_path.join(CONSENSUS_CONFIG_FILE); Ok(Self { components, code_path: chain_config.link_to_code.clone(), general_config, secrets, - en_config: enconfig, + en_config, consensus_config, }) } diff --git a/zkstack_cli/crates/zkstack/src/messages.rs b/zkstack_cli/crates/zkstack/src/messages.rs index 179f7100ef9e..4a2cbc950b44 100644 --- a/zkstack_cli/crates/zkstack/src/messages.rs +++ b/zkstack_cli/crates/zkstack/src/messages.rs @@ -197,8 +197,6 @@ pub(super) const MSG_EVM_EMULATOR_HASH_MISSING_ERR: &str = does not contain EVM emulator hash"; /// Chain genesis related messages -pub(super) const MSG_L1_SECRETS_MUST_BE_PRESENTED: &str = "L1 secret must be presented"; -pub(super) const MSG_DATABASE_MUST_BE_PRESENTED: &str = "Database secret must be presented"; pub(super) const MSG_SERVER_DB_URL_HELP: &str = "Server database url without database name"; pub(super) const MSG_SERVER_DB_NAME_HELP: &str = "Server database name"; pub(super) const MSG_PROVER_DB_URL_HELP: &str = "Prover database url without database name"; @@ -370,9 +368,6 @@ pub(super) fn msg_preparing_en_config_is_done(path: &Path) -> String { pub(super) const MSG_EXTERNAL_NODE_CONFIG_NOT_INITIALIZED: &str = "External node is not initialized"; -pub(super) const MSG_CONSENSUS_CONFIG_MISSING_ERR: &str = "Consensus config is missing"; -pub(super) const MSG_CONSENSUS_SECRETS_MISSING_ERR: &str = "Consensus secrets config is missing"; -pub(super) const MSG_CONSENSUS_SECRETS_NODE_KEY_MISSING_ERR: &str = "Consensus node key is missing"; pub(super) const MSG_BUILDING_EN: &str = "Building external node"; pub(super) const MSG_FAILED_TO_BUILD_EN_ERR: &str = "Failed to build external node"; @@ -413,8 +408,6 @@ pub(super) const MSG_PROOF_STORE_GCS_BUCKET_BASE_URL_ERR: &str = "Bucket base URL should start with gs://"; pub(super) const MSG_PROOF_STORE_GCS_CREDENTIALS_FILE_PROMPT: &str = "Provide the path to the GCS credentials file:"; -pub(super) const MSG_GENERAL_CONFIG_NOT_FOUND_ERR: &str = "General config not found"; -pub(super) const MSG_PROVER_CONFIG_NOT_FOUND_ERR: &str = "Prover config not found"; pub(super) const MSG_PROVER_INITIALIZED: &str = "Prover has been initialized successfully"; pub(super) const MSG_CREATE_GCS_BUCKET_PROMPT: &str = "Do you want to create a new GCS bucket?"; pub(super) const MSG_CREATE_GCS_BUCKET_PROJECT_ID_PROMPT: &str = "Select the project ID:"; @@ -422,8 +415,6 @@ pub(super) const MSG_CREATE_GCS_BUCKET_PROJECT_ID_NO_PROJECTS_PROMPT: &str = "Provide a project ID:"; pub(super) const MSG_CREATE_GCS_BUCKET_NAME_PROMTP: &str = "What do you want to name the bucket?"; pub(super) const MSG_CREATE_GCS_BUCKET_LOCATION_PROMPT: &str = "What location do you want to use? Find available locations at https://cloud.google.com/storage/docs/locations"; -pub(super) const MSG_PROOF_COMPRESSOR_CONFIG_NOT_FOUND_ERR: &str = - "Proof compressor config not found"; pub(super) const MSG_DOWNLOADING_SETUP_COMPRESSOR_KEY_SPINNER: &str = "Downloading compressor setup key..."; pub(super) const MSG_DOWNLOAD_SETUP_COMPRESSOR_KEY_PROMPT: &str = @@ -569,7 +560,6 @@ pub(super) fn msg_updating_chain(chain: &str) -> String { pub(super) const MSG_RECEIPT_MISSING: &str = "receipt missing"; pub(super) const MSG_STATUS_MISSING: &str = "status missing"; pub(super) const MSG_TRANSACTION_FAILED: &str = "transaction failed"; -pub(super) const MSG_API_CONFIG_MISSING: &str = "api config missing"; pub(super) const MSG_MULTICALL3_CONTRACT_NOT_CONFIGURED: &str = "multicall3 contract not configured"; pub(super) const MSG_GOVERNOR_PRIVATE_KEY_NOT_SET: &str = "governor private key not set"; diff --git a/zkstack_cli/crates/zkstack/src/utils/consensus.rs b/zkstack_cli/crates/zkstack/src/utils/consensus.rs index 0a1287067434..7e4273e4c253 100644 --- a/zkstack_cli/crates/zkstack/src/utils/consensus.rs +++ b/zkstack_cli/crates/zkstack/src/utils/consensus.rs @@ -1,31 +1,9 @@ use anyhow::Context as _; -use secrecy::{ExposeSecret, Secret}; -use zkstack_cli_config::ChainConfig; -use zksync_config::configs::consensus::{ - AttesterPublicKey, AttesterSecretKey, ConsensusSecrets, GenesisSpec, NodePublicKey, - NodeSecretKey, ProtocolVersion, ValidatorPublicKey, ValidatorSecretKey, WeightedAttester, - WeightedValidator, -}; +use serde::{Deserialize, Serialize}; +use zkstack_cli_config::{raw::PatchedConfig, ChainConfig}; use zksync_consensus_crypto::{Text, TextFmt}; use zksync_consensus_roles::{attester, node, validator}; -pub(crate) fn parse_attester_committee( - attesters: &[WeightedAttester], -) -> anyhow::Result { - let attesters: Vec<_> = attesters - .iter() - .enumerate() - .map(|(i, v)| { - Ok(attester::WeightedAttester { - key: Text::new(&v.key.0).decode().context("key").context(i)?, - weight: v.weight, - }) - }) - .collect::>() - .context("attesters")?; - attester::Committee::new(attesters).context("Committee::new()") -} - #[derive(Debug, Clone)] pub struct ConsensusSecretKeys { validator_key: validator::SecretKey, @@ -53,56 +31,93 @@ fn get_consensus_public_keys(consensus_keys: &ConsensusSecretKeys) -> ConsensusP } } -pub fn get_genesis_specs( +/// Mirrors key–address pair used in the consensus config. +#[derive(Debug, Serialize)] +pub(crate) struct KeyAndAddress { + pub key: String, + pub addr: String, +} + +#[derive(Debug, Serialize, Deserialize)] +struct Weighted { + key: String, + weight: u64, +} + +impl Weighted { + fn new(key: String, weight: u64) -> Self { + Self { key, weight } + } +} + +pub(crate) fn read_attester_committee_yaml( + raw_yaml: serde_yaml::Value, +) -> anyhow::Result { + #[derive(Debug, Deserialize)] + struct SetAttesterCommitteeFile { + attesters: Vec, + } + + let file: SetAttesterCommitteeFile = + serde_yaml::from_value(raw_yaml).context("invalid attester committee format")?; + let attesters: Vec<_> = file + .attesters + .iter() + .enumerate() + .map(|(i, v)| { + Ok(attester::WeightedAttester { + key: Text::new(&v.key).decode().context("key").context(i)?, + weight: v.weight, + }) + }) + .collect::>() + .context("attesters")?; + attester::Committee::new(attesters).context("Committee::new()") +} + +pub fn set_genesis_specs( + general: &mut PatchedConfig, chain_config: &ChainConfig, consensus_keys: &ConsensusSecretKeys, -) -> GenesisSpec { +) -> anyhow::Result<()> { let public_keys = get_consensus_public_keys(consensus_keys); let validator_key = public_keys.validator_key.encode(); let attester_key = public_keys.attester_key.encode(); + let leader = validator_key.clone(); - let validator = WeightedValidator { - key: ValidatorPublicKey(validator_key.clone()), - weight: 1, - }; - let attester = WeightedAttester { - key: AttesterPublicKey(attester_key), - weight: 1, - }; - let leader = ValidatorPublicKey(validator_key); - - GenesisSpec { - chain_id: chain_config.chain_id, - protocol_version: ProtocolVersion(1), - validators: vec![validator], - attesters: vec![attester], - leader, - registry_address: None, - seed_peers: [].into(), - } + general.insert( + "consensus.genesis_spec.chain_id", + chain_config.chain_id.as_u64(), + )?; + general.insert("consensus.genesis_spec.protocol_version", 1_u64)?; + general.insert_yaml( + "consensus.genesis_spec.validators", + [Weighted::new(validator_key, 1)], + )?; + general.insert_yaml( + "consensus.genesis_spec.attesters", + [Weighted::new(attester_key, 1)], + )?; + general.insert("consensus.genesis_spec.leader", leader)?; + Ok(()) } -pub fn get_consensus_secrets(consensus_keys: &ConsensusSecretKeys) -> ConsensusSecrets { +pub(crate) fn set_consensus_secrets( + secrets: &mut PatchedConfig, + consensus_keys: &ConsensusSecretKeys, +) -> anyhow::Result<()> { let validator_key = consensus_keys.validator_key.encode(); let attester_key = consensus_keys.attester_key.encode(); let node_key = consensus_keys.node_key.encode(); - - ConsensusSecrets { - validator_key: Some(ValidatorSecretKey(Secret::new(validator_key))), - attester_key: Some(AttesterSecretKey(Secret::new(attester_key))), - node_key: Some(NodeSecretKey(Secret::new(node_key))), - } -} - -pub fn node_public_key(secrets: &ConsensusSecrets) -> anyhow::Result> { - Ok(node_key(secrets)?.map(|node_secret_key| NodePublicKey(node_secret_key.public().encode()))) -} -fn node_key(secrets: &ConsensusSecrets) -> anyhow::Result> { - read_secret_text(secrets.node_key.as_ref().map(|x| &x.0)) + secrets.insert("consensus.validator_key", validator_key)?; + secrets.insert("consensus.attester_key", attester_key)?; + secrets.insert("consensus.node_key", node_key)?; + Ok(()) } -fn read_secret_text(text: Option<&Secret>) -> anyhow::Result> { - text.map(|text| Text::new(text.expose_secret()).decode()) - .transpose() - .map_err(|_| anyhow::format_err!("invalid format")) +pub fn node_public_key(secret_key: &str) -> anyhow::Result { + let secret_key: node::SecretKey = Text::new(secret_key) + .decode() + .context("invalid node key format")?; + Ok(secret_key.public().encode()) }