diff --git a/.github/workflows/ci-core-reusable.yml b/.github/workflows/ci-core-reusable.yml index da3e2d5abb56..7cada37610c0 100644 --- a/.github/workflows/ci-core-reusable.yml +++ b/.github/workflows/ci-core-reusable.yml @@ -357,10 +357,17 @@ jobs: run: | ci_run zkstack dev test build + - name: Build tested binaries + run: | + ci_run zkstack server build + ci_run zkstack external-node build + ci_run zkstack contract-verifier build + - 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 run --chain era &> ${{ env.SERVER_LOGS_DIR }}/contract-verifier-rollup.log & + ci_run zkstack contract-verifier wait --chain era --verbose - name: Run servers run: | @@ -375,10 +382,14 @@ jobs: --components=api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads,vm_runner_bwip,vm_playground,da_dispatcher,consensus \ &> ${{ env.SERVER_LOGS_DIR }}/consensus.log & - ci_run sleep 5 + ci_run zkstack server wait --ignore-prerequisites --verbose --chain era + ci_run zkstack server wait --ignore-prerequisites --verbose --chain validium + ci_run zkstack server wait --ignore-prerequisites --verbose --chain custom_token + ci_run zkstack server wait --ignore-prerequisites --verbose --chain consensus - - name: Setup attester committee for the consensus chain + - 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 - name: Run integration tests @@ -417,6 +428,11 @@ jobs: ci_run zkstack external-node run --ignore-prerequisites --chain validium &> ${{ env.EXTERNAL_NODE_LOGS_DIR }}/validium.log & ci_run zkstack external-node run --ignore-prerequisites --chain custom_token &> ${{ env.EXTERNAL_NODE_LOGS_DIR }}/custom_token.log & ci_run zkstack external-node run --ignore-prerequisites --chain consensus --enable-consensus &> ${{ env.EXTERNAL_NODE_LOGS_DIR }}/consensus.log & + + ci_run zkstack external-node wait --ignore-prerequisites --verbose --chain era + ci_run zkstack external-node wait --ignore-prerequisites --verbose --chain validium + ci_run zkstack external-node wait --ignore-prerequisites --verbose --chain custom_token + ci_run zkstack external-node wait --ignore-prerequisites --verbose --chain consensus - name: Run integration tests en run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2f29fe98f0e6..a4370457fecb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,6 @@ jobs: outputs: core: ${{ steps.changed-files.outputs.core_any_changed }} prover: ${{ steps.changed-files.outputs.prover_any_changed }} - zkstack_cli: ${{ steps.changed-files.outputs.zkstack_cli_any_changed }} docs: ${{ steps.changed-files.outputs.docs_any_changed }} all: ${{ steps.changed-files.outputs.all_any_changed }} steps: @@ -178,6 +177,7 @@ jobs: image_tag_suffix: ${{ needs.setup.outputs.image_tag_suffix }}-avx512 action: "build" WITNESS_GENERATOR_RUST_FLAGS: "-Ctarget_feature=+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl" + ERA_BELLMAN_CUDA_RELEASE: ${{ vars.ERA_BELLMAN_CUDA_RELEASE }} secrets: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/deploy-core-docs.yml b/.github/workflows/deploy-core-docs.yml new file mode 100644 index 000000000000..f01c56f68c3c --- /dev/null +++ b/.github/workflows/deploy-core-docs.yml @@ -0,0 +1,67 @@ +name: Deploy core docs + +on: + push: + branches: + - "main" + tags: + - "core-v*.*.*" + paths: + - 'docs/**' + - '.github/workflows/deploy-core-docs.yml' + pull_request: + paths: + - 'docs/**' + - '.github/workflows/deploy-core-docs.yml' + workflow_dispatch: + inputs: + ref: + description: "Branch, tag or commit to deploy the core docs. If empty, use the ref that triggered the workflow." + required: false + default: "" + version: + type: string + description: "Version of the documentation to deploy" + required: false + default: "latest" + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + + deploy-core-docs: + runs-on: ubuntu-latest + permissions: + contents: write + env: + DOCS_DIR: 'docs' + PROJECT: 'core' + ENABLE_TESTS: false + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + ref: ${{ inputs.ref || '' }} + + - name: Extract version from tag + if: startsWith(github.ref, 'refs/tags/') + id: extract-version + shell: 'bash -ex {0}' + run: | + TAG="${{ github.ref_name }}" + VERSION="${TAG#*-}" + echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" + + - name: Deploy core docs + uses: matter-labs/deploy-mdbooks@73f638643d1be948d1002fe5433747f4a3e37a29 # v1 + with: + version: ${{ inputs.version || steps.extract-version.outputs.version || github.ref_name }} + docs-dir: ${{ env.DOCS_DIR }} + github-token: ${{ secrets.GITHUB_TOKEN }} + enable-tests: ${{ env.ENABLE_TESTS }} + project: ${{ env.PROJECT }} + deploy: ${{ github.event_name != 'pull_request' }} diff --git a/.github/workflows/deploy-prover-docs.yml b/.github/workflows/deploy-prover-docs.yml new file mode 100644 index 000000000000..7f797c61cf5a --- /dev/null +++ b/.github/workflows/deploy-prover-docs.yml @@ -0,0 +1,67 @@ +name: Deploy prover docs + +on: + push: + branches: + - "main" + tags: + - "prover-v*.*.*" + paths: + - 'prover/docs/**' + - '.github/workflows/deploy-prover-docs.yml' + pull_request: + paths: + - 'prover/docs/**' + - '.github/workflows/deploy-prover-docs.yml' + workflow_dispatch: + inputs: + ref: + description: "Branch, tag or commit to deploy the prover docs. If empty, use the ref that triggered the workflow." + required: false + default: "" + version: + type: string + description: "Version of the documentation to deploy" + required: false + default: "latest" + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + + deploy-prover-docs: + runs-on: ubuntu-latest + permissions: + contents: write + env: + DOCS_DIR: 'prover/docs' + PROJECT: 'prover' + ENABLE_TESTS: false + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + ref: ${{ inputs.ref || '' }} + + - name: Extract version from tag + if: startsWith(github.ref, 'refs/tags/') + id: extract-version + shell: 'bash -ex {0}' + run: | + TAG="${{ github.ref_name }}" + VERSION="${TAG#*-}" + echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" + + - name: Deploy prover docs + uses: matter-labs/deploy-mdbooks@73f638643d1be948d1002fe5433747f4a3e37a29 # v1 + with: + version: ${{ inputs.version || steps.extract-version.outputs.version || github.ref_name }} + docs-dir: ${{ env.DOCS_DIR }} + github-token: ${{ secrets.GITHUB_TOKEN }} + enable-tests: ${{ env.ENABLE_TESTS }} + project: ${{ env.PROJECT }} + deploy: ${{ github.event_name != 'pull_request' }} diff --git a/.github/workflows/new-build-contract-verifier-template.yml b/.github/workflows/new-build-contract-verifier-template.yml index 7e48968a65c1..7d75f81fb73c 100644 --- a/.github/workflows/new-build-contract-verifier-template.yml +++ b/.github/workflows/new-build-contract-verifier-template.yml @@ -212,7 +212,8 @@ jobs: uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: context: . - push: ${{ inputs.action == 'push' }} + load: true + platforms: ${{ matrix.platforms }} file: docker/${{ matrix.components }}/Dockerfile build-args: | SCCACHE_GCS_BUCKET=matterlabs-infra-sccache-storage @@ -220,23 +221,16 @@ jobs: SCCACHE_GCS_RW_MODE=READ_WRITE RUSTC_WRAPPER=sccache tags: | - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:latest - matterlabs/${{ matrix.components }}:latest - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:latest2.0 - matterlabs/${{ matrix.components }}:latest2.0 - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA }} - matterlabs/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA }} - matterlabs/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} - matterlabs/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }} - matterlabs/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} - matterlabs/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }} + us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} matterlabs/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} + - name: Push docker image + if: ${{ inputs.action == 'push' }} + run: | + docker push us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} + docker push matterlabs/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} + + create_manifest: name: Create release manifest runs-on: matterlabs-ci-runner diff --git a/.github/workflows/new-build-core-template.yml b/.github/workflows/new-build-core-template.yml index 350d689c4572..ab3854733e62 100644 --- a/.github/workflows/new-build-core-template.yml +++ b/.github/workflows/new-build-core-template.yml @@ -219,35 +219,28 @@ jobs: docker login -u ${{ secrets.DOCKERHUB_USER }} -p ${{ secrets.DOCKERHUB_TOKEN }} gcloud auth configure-docker us-docker.pkg.dev -q - - name: Build and push + - name: Build docker image uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: context: . - push: ${{ inputs.action == 'push' }} + load: true + platforms: ${{ matrix.platforms }} file: docker/${{ matrix.components }}/Dockerfile build-args: | SCCACHE_GCS_BUCKET=matterlabs-infra-sccache-storage SCCACHE_GCS_SERVICE_ACCOUNT=gha-ci-runners@matterlabs-infra.iam.gserviceaccount.com SCCACHE_GCS_RW_MODE=READ_WRITE RUSTC_WRAPPER=sccache - tags: | - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:latest - matterlabs/${{ matrix.components }}:latest - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:latest2.0 - matterlabs/${{ matrix.components }}:latest2.0 - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA }} - matterlabs/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA }} - matterlabs/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} - matterlabs/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }} - matterlabs/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} - matterlabs/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} - us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }} + tags: | + us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} matterlabs/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} + - name: Push docker image + if: ${{ inputs.action == 'push' }} + run: | + docker push us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} + docker push matterlabs/${{ matrix.components }}:${{ env.IMAGE_TAG_SHA_TS }}-${{ env.PLATFORM }} + create_manifest: name: Create release manifest runs-on: matterlabs-ci-runner @@ -269,13 +262,11 @@ jobs: - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 - name: login to Docker registries - shell: bash run: | docker login -u ${{ secrets.DOCKERHUB_USER }} -p ${{ secrets.DOCKERHUB_TOKEN }} gcloud auth configure-docker us-docker.pkg.dev -q - name: Create Docker manifest - shell: bash run: | docker_repositories=("matterlabs/${{ matrix.component.name }}" "us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.component.name }}") platforms=${{ matrix.component.platform }} diff --git a/.github/workflows/new-build-prover-template.yml b/.github/workflows/new-build-prover-template.yml index 046711d679e8..ea1dcab4b122 100644 --- a/.github/workflows/new-build-prover-template.yml +++ b/.github/workflows/new-build-prover-template.yml @@ -97,6 +97,7 @@ jobs: - prover-job-monitor - proof-fri-gpu-compressor - prover-autoscaler + - circuit-prover-gpu steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: @@ -152,17 +153,29 @@ jobs: uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 with: context: . - push: ${{ inputs.action == 'push' }} + load: true build-args: | CUDA_ARCH=${{ inputs.CUDA_ARCH }} SCCACHE_GCS_BUCKET=matterlabs-infra-sccache-storage SCCACHE_GCS_SERVICE_ACCOUNT=gha-ci-runners@matterlabs-infra.iam.gserviceaccount.com SCCACHE_GCS_RW_MODE=READ_WRITE RUSTC_WRAPPER=sccache + PROTOCOL_VERSION=${{ env.PROTOCOL_VERSION }} + ERA_BELLMAN_CUDA_RELEASE=${{ inputs.ERA_BELLMAN_CUDA_RELEASE }} file: docker/${{ matrix.components }}/Dockerfile tags: | us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ env.IMAGE_TAG_SHA_TS }} matterlabs/${{ matrix.components }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ env.IMAGE_TAG_SHA_TS }} + us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} + matterlabs/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} + + - name: Push docker image + if: ${{ inputs.action == 'push' }} + run: | + docker push us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ env.IMAGE_TAG_SHA_TS }} + docker push matterlabs/${{ matrix.components }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ env.IMAGE_TAG_SHA_TS }} + docker push us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} + docker push matterlabs/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} copy-images: name: Copy images between docker registries @@ -189,6 +202,10 @@ jobs: 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: | @@ -196,3 +213,6 @@ jobs: 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/new-build-witness-generator-template.yml b/.github/workflows/new-build-witness-generator-template.yml index 2f1fc0b2dd86..7362cb609a16 100644 --- a/.github/workflows/new-build-witness-generator-template.yml +++ b/.github/workflows/new-build-witness-generator-template.yml @@ -9,6 +9,10 @@ on: description: "DOCKERHUB_TOKEN" required: true inputs: + ERA_BELLMAN_CUDA_RELEASE: + description: "ERA_BELLMAN_CUDA_RELEASE" + type: string + required: true image_tag_suffix: description: "Optional suffix to override tag name generation" type: string @@ -127,7 +131,12 @@ jobs: SCCACHE_GCS_SERVICE_ACCOUNT=gha-ci-runners@matterlabs-infra.iam.gserviceaccount.com SCCACHE_GCS_RW_MODE=READ_WRITE RUSTC_WRAPPER=sccache + PROTOCOL_VERSION=${{ env.PROTOCOL_VERSION }} + ERA_BELLMAN_CUDA_RELEASE=${{ inputs.ERA_BELLMAN_CUDA_RELEASE }} + RUST_FLAGS=${{ inputs.WITNESS_GENERATOR_RUST_FLAGS }} file: docker/${{ matrix.components }}/Dockerfile tags: | us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ env.IMAGE_TAG_SHA_TS }} matterlabs/${{ matrix.components }}:2.0-${{ env.PROTOCOL_VERSION }}-${{ env.IMAGE_TAG_SHA_TS }} + us-docker.pkg.dev/matterlabs-infra/matterlabs-docker/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} + matterlabs/${{ matrix.components }}:2.0-${{ env.IMAGE_TAG_SHA_TS }} diff --git a/.github/workflows/release-test-stage.yml b/.github/workflows/release-test-stage.yml index 18708420dab0..eb75ab179b8e 100644 --- a/.github/workflows/release-test-stage.yml +++ b/.github/workflows/release-test-stage.yml @@ -61,10 +61,11 @@ jobs: build-push-core-images: name: Build and push images needs: [setup, changed_files] - uses: ./.github/workflows/build-core-template.yml + uses: ./.github/workflows/new-build-core-template.yml if: needs.changed_files.outputs.core == 'true' || needs.changed_files.outputs.all == 'true' with: image_tag_suffix: ${{ needs.setup.outputs.image_tag_suffix }} + action: "push" secrets: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} @@ -84,10 +85,11 @@ jobs: build-push-contract-verifier: name: Build and push images needs: [setup, changed_files] - uses: ./.github/workflows/build-contract-verifier-template.yml + uses: ./.github/workflows/new-build-contract-verifier-template.yml if: needs.changed_files.outputs.core == 'true' || needs.changed_files.outputs.all == 'true' with: image_tag_suffix: ${{ needs.setup.outputs.image_tag_suffix }} + action: "push" secrets: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} @@ -95,12 +97,13 @@ jobs: build-push-prover-images: name: Build and push images needs: [setup, changed_files] - uses: ./.github/workflows/build-prover-template.yml + uses: ./.github/workflows/new-build-prover-template.yml if: needs.changed_files.outputs.prover == 'true' || needs.changed_files.outputs.all == 'true' with: image_tag_suffix: ${{ needs.setup.outputs.image_tag_suffix }} ERA_BELLMAN_CUDA_RELEASE: ${{ vars.ERA_BELLMAN_CUDA_RELEASE }} CUDA_ARCH: "60;70;75;80;89" + action: "push" secrets: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} @@ -108,13 +111,14 @@ jobs: build-push-witness-generator-image-avx512: name: Build and push prover images with avx512 instructions needs: [setup, changed_files] - uses: ./.github/workflows/build-witness-generator-template.yml + uses: ./.github/workflows/new-build-witness-generator-template.yml if: needs.changed_files.outputs.prover == 'true' || needs.changed_files.outputs.all == 'true' with: image_tag_suffix: ${{ needs.setup.outputs.image_tag_suffix }}-avx512 ERA_BELLMAN_CUDA_RELEASE: ${{ vars.ERA_BELLMAN_CUDA_RELEASE }} CUDA_ARCH: "60;70;75;80;89" WITNESS_GENERATOR_RUST_FLAGS: "-Ctarget_feature=+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl " + action: "push" secrets: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index f27bd256d8cf..f78b4764e676 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9754,7 +9754,6 @@ dependencies = [ "zksync_contracts", "zksync_multivm", "zksync_types", - "zksync_utils", "zksync_vlog", "zksync_vm2", ] @@ -10571,6 +10570,7 @@ dependencies = [ "anyhow", "bincode", "chrono", + "const-decoder", "ethabi", "hex", "num_enum 0.7.3", @@ -10578,6 +10578,7 @@ dependencies = [ "serde", "serde_json", "serde_with", + "sha2 0.10.8", "strum", "thiserror", "tiny-keccak 2.0.2", @@ -10912,7 +10913,6 @@ dependencies = [ "zksync_dal", "zksync_node_test_utils", "zksync_types", - "zksync_utils", ] [[package]] @@ -10970,11 +10970,11 @@ version = "0.1.0" dependencies = [ "bincode", "envy", - "ethabi", "hex", "once_cell", "serde", "serde_json", + "zksync_basic_types", "zksync_utils", ] @@ -11122,7 +11122,6 @@ dependencies = [ "zksync_system_constants", "zksync_test_account", "zksync_types", - "zksync_utils", "zksync_vm_interface", ] @@ -11551,7 +11550,6 @@ dependencies = [ "zksync_system_constants", "zksync_test_account", "zksync_types", - "zksync_utils", "zksync_vm2", "zksync_vm_interface", ] @@ -11604,7 +11602,6 @@ dependencies = [ "zksync_state_keeper", "zksync_system_constants", "zksync_types", - "zksync_utils", "zksync_vm_executor", "zksync_web3_decl", ] @@ -11623,6 +11620,7 @@ dependencies = [ "thiserror", "tokio", "tracing", + "vise", "zksync_concurrency", "zksync_config", "zksync_consensus_bft", @@ -11778,7 +11776,6 @@ dependencies = [ "zksync_multivm", "zksync_system_constants", "zksync_types", - "zksync_utils", ] [[package]] @@ -11823,6 +11820,7 @@ dependencies = [ "vise", "zksync_concurrency", "zksync_config", + "zksync_consensus_roles", "zksync_contracts", "zksync_dal", "zksync_eth_client", @@ -11833,7 +11831,6 @@ dependencies = [ "zksync_state_keeper", "zksync_system_constants", "zksync_types", - "zksync_utils", "zksync_vm_executor", "zksync_web3_decl", ] @@ -12080,7 +12077,6 @@ dependencies = [ "zksync_health_check", "zksync_object_store", "zksync_types", - "zksync_utils", "zksync_web3_decl", ] @@ -12161,7 +12157,6 @@ dependencies = [ "zksync_system_constants", "zksync_test_account", "zksync_types", - "zksync_utils", "zksync_vm_executor", ] @@ -12240,7 +12235,6 @@ dependencies = [ "zksync_eth_signer", "zksync_system_constants", "zksync_types", - "zksync_utils", ] [[package]] @@ -12275,7 +12269,6 @@ dependencies = [ "zksync_protobuf", "zksync_protobuf_build", "zksync_system_constants", - "zksync_utils", ] [[package]] @@ -12284,16 +12277,12 @@ version = "0.1.0" dependencies = [ "anyhow", "assert_matches", - "const-decoder", "futures 0.3.31", "once_cell", "reqwest 0.12.9", "serde_json", - "thiserror", "tokio", "tracing", - "zk_evm 0.133.0", - "zksync_basic_types", "zksync_vlog", ] @@ -12358,7 +12347,6 @@ dependencies = [ "zksync_dal", "zksync_multivm", "zksync_types", - "zksync_utils", ] [[package]] @@ -12409,7 +12397,6 @@ dependencies = [ "zksync_storage", "zksync_test_account", "zksync_types", - "zksync_utils", "zksync_vm_executor", "zksync_vm_interface", ] diff --git a/core/bin/system-constants-generator/src/utils.rs b/core/bin/system-constants-generator/src/utils.rs index 2c08de7970b8..e3558de3e6a1 100644 --- a/core/bin/system-constants-generator/src/utils.rs +++ b/core/bin/system-constants-generator/src/utils.rs @@ -21,14 +21,13 @@ use zksync_multivm::{ zk_evm_latest::aux_structures::Timestamp, }; use zksync_types::{ - block::L2BlockHasher, ethabi::Token, fee::Fee, fee_model::BatchFeeInput, l1::L1Tx, l2::L2Tx, - u256_to_h256, utils::storage_key_for_eth_balance, AccountTreeId, Address, Execute, - K256PrivateKey, L1BatchNumber, L1TxCommonData, L2BlockNumber, L2ChainId, Nonce, - ProtocolVersionId, StorageKey, Transaction, BOOTLOADER_ADDRESS, SYSTEM_CONTEXT_ADDRESS, - SYSTEM_CONTEXT_GAS_PRICE_POSITION, SYSTEM_CONTEXT_TX_ORIGIN_POSITION, U256, - ZKPORTER_IS_AVAILABLE, + block::L2BlockHasher, bytecode::BytecodeHash, ethabi::Token, fee::Fee, + fee_model::BatchFeeInput, l1::L1Tx, l2::L2Tx, u256_to_h256, utils::storage_key_for_eth_balance, + AccountTreeId, Address, Execute, K256PrivateKey, L1BatchNumber, L1TxCommonData, L2BlockNumber, + L2ChainId, Nonce, ProtocolVersionId, StorageKey, Transaction, BOOTLOADER_ADDRESS, + SYSTEM_CONTEXT_ADDRESS, SYSTEM_CONTEXT_GAS_PRICE_POSITION, SYSTEM_CONTEXT_TX_ORIGIN_POSITION, + U256, ZKPORTER_IS_AVAILABLE, }; -use zksync_utils::bytecode::hash_bytecode; use crate::intrinsic_costs::VmSpentResourcesResult; @@ -63,7 +62,7 @@ impl VmTracer for SpecialBootloaderTracer pub static GAS_TEST_SYSTEM_CONTRACTS: Lazy = Lazy::new(|| { let bytecode = read_bootloader_code("gas_test"); - let hash = hash_bytecode(&bytecode); + let hash = BytecodeHash::for_bytecode(&bytecode).value(); let bootloader = SystemContractCode { code: bytecode, @@ -71,7 +70,7 @@ pub static GAS_TEST_SYSTEM_CONTRACTS: Lazy = Lazy::new(|| { }; let bytecode = read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol); - let hash = hash_bytecode(&bytecode); + let hash = BytecodeHash::for_bytecode(&bytecode).value(); BaseSystemContracts { default_aa: SystemContractCode { @@ -208,12 +207,12 @@ fn default_l1_batch() -> L1BatchEnv { /// returns the amount of gas needed to perform and internal transfer, assuming no gas price /// per pubdata, i.e. under assumption that the refund will not touch any new slots. pub(super) fn execute_internal_transfer_test() -> u32 { - let raw_storage = InMemoryStorage::with_system_contracts(hash_bytecode); + let raw_storage = InMemoryStorage::with_system_contracts(); let mut storage_view = StorageView::new(raw_storage); let bootloader_balance_key = storage_key_for_eth_balance(&BOOTLOADER_ADDRESS); storage_view.set_value(bootloader_balance_key, u256_to_h256(U256([0, 0, 1, 0]))); let bytecode = read_bootloader_test_code("transfer_test"); - let hash = hash_bytecode(&bytecode); + let hash = BytecodeHash::for_bytecode(&bytecode).value(); let bootloader = SystemContractCode { code: bytecode, hash, @@ -222,7 +221,7 @@ pub(super) fn execute_internal_transfer_test() -> u32 { let l1_batch = default_l1_batch(); let bytecode = read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol); - let hash = hash_bytecode(&bytecode); + let hash = BytecodeHash::for_bytecode(&bytecode).value(); let default_aa = SystemContractCode { code: bytecode, hash, @@ -293,7 +292,7 @@ pub(super) fn execute_user_txs_in_test_gas_vm( .iter() .fold(U256::zero(), |sum, elem| sum + elem.gas_limit()); - let raw_storage = InMemoryStorage::with_system_contracts(hash_bytecode); + let raw_storage = InMemoryStorage::with_system_contracts(); let mut storage_view = StorageView::new(raw_storage); for tx in txs.iter() { diff --git a/core/bin/zksync_server/src/node_builder.rs b/core/bin/zksync_server/src/node_builder.rs index 32478ede5bf8..794c847a24d5 100644 --- a/core/bin/zksync_server/src/node_builder.rs +++ b/core/bin/zksync_server/src/node_builder.rs @@ -325,7 +325,11 @@ impl MainNodeBuilder { latest_values_cache_size: rpc_config.latest_values_cache_size() as u64, latest_values_max_block_lag: rpc_config.latest_values_max_block_lag(), }; - let vm_config = try_load_config!(self.configs.experimental_vm_config); + let vm_config = self + .configs + .experimental_vm_config + .clone() + .unwrap_or_default(); // On main node we always use master pool sink. self.node.add_layer(MasterPoolSinkLayer); @@ -597,7 +601,11 @@ impl MainNodeBuilder { } fn add_vm_playground_layer(mut self) -> anyhow::Result { - let vm_config = try_load_config!(self.configs.experimental_vm_config); + let vm_config = self + .configs + .experimental_vm_config + .clone() + .unwrap_or_default(); self.node.add_layer(VmPlaygroundLayer::new( vm_config.playground, self.genesis_config.l2_chain_id, diff --git a/core/lib/basic_types/Cargo.toml b/core/lib/basic_types/Cargo.toml index 616b959b0783..6cac4f60f615 100644 --- a/core/lib/basic_types/Cargo.toml +++ b/core/lib/basic_types/Cargo.toml @@ -11,8 +11,10 @@ keywords.workspace = true categories.workspace = true [dependencies] +const-decoder.workspace = true ethabi.workspace = true hex.workspace = true +sha2.workspace = true tiny-keccak.workspace = true thiserror.workspace = true serde = { workspace = true, features = ["derive"] } diff --git a/core/lib/utils/src/bytecode.rs b/core/lib/basic_types/src/bytecode.rs similarity index 50% rename from core/lib/utils/src/bytecode.rs rename to core/lib/basic_types/src/bytecode.rs index fcba022f9277..585ba0ef8c88 100644 --- a/core/lib/utils/src/bytecode.rs +++ b/core/lib/basic_types/src/bytecode.rs @@ -1,22 +1,42 @@ -// FIXME (PLA-1064): move to basic_types +//! Bytecode-related types and utils. +//! +//! # Bytecode kinds +//! +//! ZKsync supports 2 kinds of bytecodes: EraVM and EVM ones. +//! +//! - **EraVM** bytecodes consist of 64-bit (8-byte) instructions for the corresponding VM. +//! - **EVM** bytecodes consist of ordinary EVM opcodes, preceded with a 32-byte big-endian code length (in bytes). +//! +//! Both bytecode kinds are right-padded to consist of an integer, odd number of 32-byte words. All methods +//! in this module operate on padded bytecodes unless explicitly specified otherwise. use anyhow::Context as _; -use zk_evm::k256::sha2::{Digest, Sha256}; -use zksync_basic_types::{H256, U256}; +use sha2::{Digest, Sha256}; + +use crate::{H256, U256}; const MAX_BYTECODE_LENGTH_IN_WORDS: usize = (1 << 16) - 1; const MAX_BYTECODE_LENGTH_BYTES: usize = MAX_BYTECODE_LENGTH_IN_WORDS * 32; -#[derive(Debug, thiserror::Error, PartialEq)] +/// Errors returned from [`validate_bytecode()`]. +#[derive(Debug, thiserror::Error)] +#[non_exhaustive] pub enum InvalidBytecodeError { + /// Bytecode is too long. #[error("Bytecode too long: {0} bytes, while max {1} allowed")] BytecodeTooLong(usize, usize), - #[error("Bytecode has even number of 32-byte words")] - BytecodeLengthInWordsIsEven, + /// Bytecode length isn't divisible by 32 (i.e., bytecode cannot be represented as a sequence of 32-byte EraVM words). #[error("Bytecode length is not divisible by 32")] BytecodeLengthIsNotDivisibleBy32, + /// Bytecode has an even number of 32-byte words. + #[error("Bytecode has even number of 32-byte words")] + BytecodeLengthInWordsIsEven, } +/// Validates that the given bytecode passes basic checks (e.g., not too long). +/// +/// The performed checks are universal both for EraVM and (padded) EVM bytecodes. If you need to additionally check EVM bytecode integrity, +/// use [`trim_padded_evm_bytecode()`]. pub fn validate_bytecode(code: &[u8]) -> Result<(), InvalidBytecodeError> { let bytecode_len = code.len(); @@ -40,37 +60,79 @@ pub fn validate_bytecode(code: &[u8]) -> Result<(), InvalidBytecodeError> { Ok(()) } -fn bytes_to_chunks(bytes: &[u8]) -> Vec<[u8; 32]> { - assert_eq!( - bytes.len() % 32, - 0, - "Bytes must be divisible by 32 to split into chunks" - ); - bytes - .chunks(32) - .map(|el| { - let mut chunk = [0u8; 32]; - chunk.copy_from_slice(el); - chunk - }) - .collect() -} +/// 32-byte bytecode hash. Besides a cryptographically secure hash of the bytecode contents, contains a [`BytecodeMarker`] +/// and the bytecode length. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct BytecodeHash(H256); -/// Hashes the provided EraVM bytecode. -pub fn hash_bytecode(code: &[u8]) -> H256 { - let chunked_code = bytes_to_chunks(code); - let hash = zk_evm::zkevm_opcode_defs::utils::bytecode_to_code_hash(&chunked_code) - .expect("Invalid bytecode"); +impl BytecodeHash { + /// Hashes the provided EraVM bytecode. + pub fn for_bytecode(bytecode: &[u8]) -> Self { + Self::for_generic_bytecode(BytecodeMarker::EraVm, bytecode) + } - H256(hash) -} + /// Hashes the provided padded EVM bytecode. + pub fn for_evm_bytecode(bytecode: &[u8]) -> Self { + Self::for_generic_bytecode(BytecodeMarker::Evm, bytecode) + } -pub fn bytecode_len_in_words(bytecodehash: &H256) -> u16 { - u16::from_be_bytes([bytecodehash[2], bytecodehash[3]]) + fn for_generic_bytecode(kind: BytecodeMarker, bytecode: &[u8]) -> Self { + validate_bytecode(bytecode).expect("invalid bytecode"); + + let mut hasher = Sha256::new(); + let len = match kind { + BytecodeMarker::EraVm => (bytecode.len() / 32) as u16, + BytecodeMarker::Evm => bytecode.len() as u16, + }; + hasher.update(bytecode); + let result = hasher.finalize(); + + let mut output = [0u8; 32]; + output[..].copy_from_slice(result.as_slice()); + output[0] = kind as u8; + output[1] = 0; + output[2..4].copy_from_slice(&len.to_be_bytes()); + + Self(H256(output)) + } + + /// Returns a marker / kind of this bytecode. + pub fn marker(&self) -> BytecodeMarker { + match self.0.as_bytes()[0] { + val if val == BytecodeMarker::EraVm as u8 => BytecodeMarker::EraVm, + val if val == BytecodeMarker::Evm as u8 => BytecodeMarker::Evm, + _ => unreachable!(), + } + } + + /// Returns the length of the hashed bytecode in bytes. + pub fn len_in_bytes(&self) -> usize { + let bytes = self.0.as_bytes(); + let raw_len = u16::from_be_bytes([bytes[2], bytes[3]]); + match self.marker() { + BytecodeMarker::EraVm => raw_len as usize * 32, + BytecodeMarker::Evm => raw_len as usize, + } + } + + /// Returns the underlying hash value. + pub fn value(self) -> H256 { + self.0 + } + + /// Returns the underlying hash value interpreted as a big-endian unsigned integer. + pub fn value_u256(self) -> U256 { + crate::h256_to_u256(self.0) + } } -pub fn bytecode_len_in_bytes(bytecodehash: H256) -> usize { - bytecode_len_in_words(&bytecodehash) as usize * 32 +impl TryFrom for BytecodeHash { + type Error = anyhow::Error; + + fn try_from(raw_hash: H256) -> Result { + BytecodeMarker::new(raw_hash).context("unknown bytecode hash marker")?; + Ok(Self(raw_hash)) + } } /// Bytecode marker encoded in the first byte of the bytecode hash. @@ -94,26 +156,10 @@ impl BytecodeMarker { } } -/// Hashes the provided EVM bytecode. The bytecode must be padded to an odd number of 32-byte words; -/// bytecodes stored in the known codes storage satisfy this requirement automatically. -pub fn hash_evm_bytecode(bytecode: &[u8]) -> H256 { - validate_bytecode(bytecode).expect("invalid EVM bytecode"); - - let mut hasher = Sha256::new(); - let len = bytecode.len() as u16; - hasher.update(bytecode); - let result = hasher.finalize(); - - let mut output = [0u8; 32]; - output[..].copy_from_slice(result.as_slice()); - output[0] = BytecodeMarker::Evm as u8; - output[1] = 0; - output[2..4].copy_from_slice(&len.to_be_bytes()); +/// Removes padding from an EVM bytecode, returning the original EVM bytecode. +pub fn trim_padded_evm_bytecode(raw: &[u8]) -> anyhow::Result<&[u8]> { + validate_bytecode(raw).context("bytecode fails basic validity checks")?; - H256(output) -} - -pub fn prepare_evm_bytecode(raw: &[u8]) -> anyhow::Result<&[u8]> { // EVM bytecodes are prefixed with a big-endian `U256` bytecode length. let bytecode_len_bytes = raw.get(..32).context("length < 32")?; let bytecode_len = U256::from_big_endian(bytecode_len_bytes); @@ -135,6 +181,7 @@ pub fn prepare_evm_bytecode(raw: &[u8]) -> anyhow::Result<&[u8]> { Ok(bytecode) } +#[doc(hidden)] // only useful for tests pub mod testonly { use const_decoder::Decoder; @@ -172,21 +219,18 @@ mod tests { #[test] fn bytecode_markers_are_valid() { - let bytecode_hash = hash_bytecode(&[0; 32]); - assert_eq!( - BytecodeMarker::new(bytecode_hash), - Some(BytecodeMarker::EraVm) - ); - let bytecode_hash = hash_evm_bytecode(&[0; 32]); - assert_eq!( - BytecodeMarker::new(bytecode_hash), - Some(BytecodeMarker::Evm) - ); + let bytecode_hash = BytecodeHash::for_bytecode(&[0; 32]); + assert_eq!(bytecode_hash.marker(), BytecodeMarker::EraVm); + assert_eq!(bytecode_hash.len_in_bytes(), 32); + + let bytecode_hash = BytecodeHash::for_evm_bytecode(&[0; 32]); + assert_eq!(bytecode_hash.marker(), BytecodeMarker::Evm); + assert_eq!(bytecode_hash.len_in_bytes(), 32); } #[test] fn preparing_evm_bytecode() { - let prepared = prepare_evm_bytecode(RAW_EVM_BYTECODE).unwrap(); + let prepared = trim_padded_evm_bytecode(RAW_EVM_BYTECODE).unwrap(); assert_eq!(prepared, PROCESSED_EVM_BYTECODE); } } diff --git a/core/lib/basic_types/src/lib.rs b/core/lib/basic_types/src/lib.rs index 5776416265d2..d79bc57cc5e1 100644 --- a/core/lib/basic_types/src/lib.rs +++ b/core/lib/basic_types/src/lib.rs @@ -29,6 +29,7 @@ pub use self::conversions::{ #[macro_use] mod macros; pub mod basic_fri_types; +pub mod bytecode; pub mod commitment; mod conversions; pub mod network; diff --git a/core/lib/contract_verifier/src/lib.rs b/core/lib/contract_verifier/src/lib.rs index aaa9c126641e..284d9921a674 100644 --- a/core/lib/contract_verifier/src/lib.rs +++ b/core/lib/contract_verifier/src/lib.rs @@ -14,13 +14,13 @@ use tokio::time; use zksync_dal::{contract_verification_dal::DeployedContractData, ConnectionPool, Core, CoreDal}; use zksync_queued_job_processor::{async_trait, JobProcessor}; use zksync_types::{ + bytecode::{trim_padded_evm_bytecode, BytecodeMarker}, contract_verification_api::{ self as api, CompilationArtifacts, VerificationIncomingRequest, VerificationInfo, VerificationRequest, }, Address, CONTRACT_DEPLOYER_ADDRESS, }; -use zksync_utils::bytecode::{prepare_evm_bytecode, BytecodeMarker}; use crate::{ compilers::{Solc, VyperInput, ZkSolc}, @@ -257,7 +257,7 @@ impl ContractVerifier { let deployed_bytecode = match bytecode_marker { BytecodeMarker::EraVm => deployed_contract.bytecode.as_slice(), - BytecodeMarker::Evm => prepare_evm_bytecode(&deployed_contract.bytecode) + BytecodeMarker::Evm => trim_padded_evm_bytecode(&deployed_contract.bytecode) .context("invalid stored EVM bytecode")?, }; diff --git a/core/lib/contract_verifier/src/tests/mod.rs b/core/lib/contract_verifier/src/tests/mod.rs index 80fc304fdd11..f66732675ce6 100644 --- a/core/lib/contract_verifier/src/tests/mod.rs +++ b/core/lib/contract_verifier/src/tests/mod.rs @@ -11,6 +11,7 @@ use zksync_dal::Connection; use zksync_node_test_utils::{create_l1_batch, create_l2_block}; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, contract_verification_api::{CompilerVersions, SourceCodeData, VerificationIncomingRequest}, get_code_key, get_known_code_key, l2::L2Tx, @@ -18,7 +19,6 @@ use zksync_types::{ Execute, L1BatchNumber, L2BlockNumber, ProtocolVersion, StorageLog, CONTRACT_DEPLOYER_ADDRESS, H256, U256, }; -use zksync_utils::bytecode::{hash_bytecode, hash_evm_bytecode}; use zksync_vm_interface::{tracer::ValidationTraces, TransactionExecutionMetrics, VmEvent}; use super::*; @@ -142,7 +142,7 @@ async fn mock_deployment( bytecode: Vec, constructor_args: &[Token], ) { - let bytecode_hash = hash_bytecode(&bytecode); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value(); let deployment = Execute::for_deploy(H256::zero(), bytecode.clone(), constructor_args); mock_deployment_inner(storage, address, bytecode_hash, bytecode, deployment).await; } @@ -163,7 +163,7 @@ async fn mock_evm_deployment( factory_deps: vec![], }; let bytecode = pad_evm_bytecode(deployed_bytecode); - let bytecode_hash = hash_evm_bytecode(&bytecode); + let bytecode_hash = BytecodeHash::for_evm_bytecode(&bytecode).value(); mock_deployment_inner(storage, address, bytecode_hash, bytecode, deployment).await; } diff --git a/core/lib/contract_verifier/src/tests/real.rs b/core/lib/contract_verifier/src/tests/real.rs index 168285279967..ba7615528e15 100644 --- a/core/lib/contract_verifier/src/tests/real.rs +++ b/core/lib/contract_verifier/src/tests/real.rs @@ -5,7 +5,7 @@ use std::{env, sync::Arc, time::Duration}; use assert_matches::assert_matches; -use zksync_utils::bytecode::validate_bytecode; +use zksync_types::bytecode::validate_bytecode; use super::*; diff --git a/core/lib/contracts/Cargo.toml b/core/lib/contracts/Cargo.toml index efe37b301e28..0a24012f1ba6 100644 --- a/core/lib/contracts/Cargo.toml +++ b/core/lib/contracts/Cargo.toml @@ -11,9 +11,9 @@ keywords.workspace = true categories.workspace = true [dependencies] +zksync_basic_types.workspace = true zksync_utils.workspace = true -ethabi.workspace = true serde_json.workspace = true serde.workspace = true once_cell.workspace = true diff --git a/core/lib/contracts/src/lib.rs b/core/lib/contracts/src/lib.rs index ad9f7739ba0d..63fdcd0c8545 100644 --- a/core/lib/contracts/src/lib.rs +++ b/core/lib/contracts/src/lib.rs @@ -10,10 +10,14 @@ use std::{ path::{Path, PathBuf}, }; -use ethabi::{ethereum_types::H256, Contract, Event, Function}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; -use zksync_utils::{bytecode::hash_bytecode, env::Workspace}; +use zksync_basic_types::{ + bytecode::BytecodeHash, + ethabi::{Contract, Event, Function}, + H256, +}; +use zksync_utils::env::Workspace; mod serde_bytecode; pub mod test_contracts; @@ -408,14 +412,14 @@ impl PartialEq for BaseSystemContracts { impl BaseSystemContracts { fn load_with_bootloader(bootloader_bytecode: Vec) -> Self { - let hash = hash_bytecode(&bootloader_bytecode); + let hash = BytecodeHash::for_bytecode(&bootloader_bytecode).value(); let bootloader = SystemContractCode { code: bootloader_bytecode, hash, }; let bytecode = read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol); - let hash = hash_bytecode(&bytecode); + let hash = BytecodeHash::for_bytecode(&bytecode).value(); let default_aa = SystemContractCode { code: bytecode, hash, @@ -437,7 +441,7 @@ impl BaseSystemContracts { /// Loads the latest EVM emulator for these base system contracts. Logically, it only makes sense to do for the latest protocol version. pub fn with_latest_evm_emulator(mut self) -> Self { let bytecode = read_sys_contract_bytecode("", "EvmEmulator", ContractLanguage::Yul); - let hash = hash_bytecode(&bytecode); + let hash = BytecodeHash::for_bytecode(&bytecode).value(); self.evm_emulator = Some(SystemContractCode { code: bytecode, hash, diff --git a/core/lib/contracts/src/serde_bytecode.rs b/core/lib/contracts/src/serde_bytecode.rs index 43de12e8ddd1..8f250fe4672a 100644 --- a/core/lib/contracts/src/serde_bytecode.rs +++ b/core/lib/contracts/src/serde_bytecode.rs @@ -1,7 +1,7 @@ use std::fmt; -use ethabi::ethereum_types::U256; use serde::{de, de::SeqAccess, ser, ser::SerializeSeq, Deserializer, Serializer}; +use zksync_basic_types::U256; pub(super) fn serialize(bytes: &[u8], serializer: S) -> Result { if bytes.len() % 32 != 0 { @@ -43,8 +43,8 @@ pub(super) fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result< #[cfg(test)] mod tests { - use ethabi::ethereum_types::{H256, U256}; use serde::{Deserialize, Serialize}; + use zksync_basic_types::{H256, U256}; use crate::SystemContractCode; diff --git a/core/lib/contracts/src/test_contracts.rs b/core/lib/contracts/src/test_contracts.rs index a670d930f049..c694743fc9e1 100644 --- a/core/lib/contracts/src/test_contracts.rs +++ b/core/lib/contracts/src/test_contracts.rs @@ -1,5 +1,8 @@ -use ethabi::{ethereum_types::U256, Bytes, Token}; use serde::Deserialize; +use zksync_basic_types::{ + ethabi::{Bytes, Token}, + U256, +}; use crate::get_loadnext_contract; diff --git a/core/lib/dal/Cargo.toml b/core/lib/dal/Cargo.toml index db03b8de9825..807a41ae0876 100644 --- a/core/lib/dal/Cargo.toml +++ b/core/lib/dal/Cargo.toml @@ -15,7 +15,6 @@ links = "zksync_dal_proto" [dependencies] vise.workspace = true zksync_vm_interface.workspace = true -zksync_utils.workspace = true zksync_system_constants.workspace = true zksync_contracts.workspace = true zksync_types.workspace = true diff --git a/core/lib/dal/src/contract_verification_dal.rs b/core/lib/dal/src/contract_verification_dal.rs index 0708063dff60..57bea5392cf8 100644 --- a/core/lib/dal/src/contract_verification_dal.rs +++ b/core/lib/dal/src/contract_verification_dal.rs @@ -567,11 +567,11 @@ mod tests { use std::collections::HashMap; use zksync_types::{ + bytecode::BytecodeHash, contract_verification_api::{CompilerVersions, SourceCodeData}, tx::IncludedTxLocation, Execute, L1BatchNumber, L2BlockNumber, ProtocolVersion, }; - use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::{tracer::ValidationTraces, TransactionExecutionMetrics}; use super::*; @@ -598,7 +598,7 @@ mod tests { let deployed_address = Address::repeat_byte(12); let mut tx = mock_l2_transaction(); let bytecode = vec![1; 32]; - let bytecode_hash = hash_bytecode(&bytecode); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value(); tx.execute = Execute::for_deploy(H256::zero(), bytecode.clone(), &[]); conn.transactions_dal() .insert_transaction_l2( diff --git a/core/lib/multivm/Cargo.toml b/core/lib/multivm/Cargo.toml index 27130bc2720d..f2046b77d9cc 100644 --- a/core/lib/multivm/Cargo.toml +++ b/core/lib/multivm/Cargo.toml @@ -26,7 +26,6 @@ circuit_sequencer_api_1_5_0.workspace = true zksync_types.workspace = true zksync_contracts.workspace = true -zksync_utils.workspace = true zksync_system_constants.workspace = true zksync_vm_interface.workspace = true zksync_mini_merkle_tree.workspace = true diff --git a/core/lib/multivm/src/glue/tracers/mod.rs b/core/lib/multivm/src/glue/tracers/mod.rs index bf2f67cae501..f5a854ecbaaf 100644 --- a/core/lib/multivm/src/glue/tracers/mod.rs +++ b/core/lib/multivm/src/glue/tracers/mod.rs @@ -7,7 +7,7 @@ //! Different VM versions may have distinct requirements and types for Tracers. To accommodate these differences, //! this module defines one primary trait: //! -//! - `MultiVMTracer`: This trait represents a tracer that can be converted into a tracer for +//! - `MultiVmTracer`: This trait represents a tracer that can be converted into a tracer for //! a specific VM version. //! //! Specific traits for each VM version, which support Custom Tracers: @@ -19,22 +19,22 @@ //! into a form compatible with the vm_virtual_blocks version. //! It defines a method `vm_virtual_blocks` for obtaining a boxed tracer. //! -//! For `MultiVMTracer` to be implemented, the Tracer must implement all N currently +//! For `MultiVmTracer` to be implemented, the Tracer must implement all N currently //! existing sub-traits. //! //! ## Adding a new VM version //! -//! To add support for one more VM version to MultiVMTracer, one needs to: +//! To add support for one more VM version to MultiVmTracer, one needs to: //! - Create a new trait performing conversion to the specified VM tracer, e.g., `IntoTracer`. -//! - Add this trait as a trait bound to the `MultiVMTracer`. -//! - Add this trait as a trait bound for `T` in `MultiVMTracer` implementation. +//! - Add this trait as a trait bound to the `MultiVmTracer`. +//! - Add this trait as a trait bound for `T` in `MultiVmTracer` implementation. //! - Implement the trait for `T` with a bound to `VmTracer` for a specific version. use crate::{interface::storage::WriteStorage, tracers::old::OldTracers, HistoryMode}; -pub type MultiVmTracerPointer = Box>; +pub type MultiVmTracerPointer = Box>; -pub trait MultiVMTracer: +pub trait MultiVmTracer: IntoLatestTracer + IntoVmVirtualBlocksTracer + IntoVmRefundsEnhancementTracer @@ -168,7 +168,7 @@ where } } -impl MultiVMTracer for T +impl MultiVmTracer for T where S: WriteStorage, H: HistoryMode, diff --git a/core/lib/multivm/src/lib.rs b/core/lib/multivm/src/lib.rs index 1cba2c0fb92b..fc4085d9b021 100644 --- a/core/lib/multivm/src/lib.rs +++ b/core/lib/multivm/src/lib.rs @@ -10,7 +10,7 @@ pub use zksync_vm_interface as interface; pub use crate::{ glue::{ history_mode::HistoryMode, - tracers::{MultiVMTracer, MultiVmTracerPointer}, + tracers::{MultiVmTracer, MultiVmTracerPointer}, }, versions::{ vm_1_3_2, vm_1_4_1, vm_1_4_2, vm_boojum_integration, vm_fast, vm_latest, vm_m5, vm_m6, diff --git a/core/lib/multivm/src/pubdata_builders/utils.rs b/core/lib/multivm/src/pubdata_builders/utils.rs index 57361a674fb7..83c9b9317640 100644 --- a/core/lib/multivm/src/pubdata_builders/utils.rs +++ b/core/lib/multivm/src/pubdata_builders/utils.rs @@ -1,6 +1,5 @@ use zksync_mini_merkle_tree::MiniMerkleTree; -use zksync_types::web3::keccak256; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, web3::keccak256}; use crate::interface::pubdata::L1MessengerL2ToL1Log; @@ -49,8 +48,9 @@ pub(crate) fn build_chained_bytecode_hash(published_bytecodes: &[Vec]) -> Ve let mut chained_bytecode_hash = vec![0u8; 32]; for bytecode in published_bytecodes { - let hash = hash_bytecode(bytecode).to_fixed_bytes(); - + let hash = BytecodeHash::for_bytecode(bytecode) + .value() + .to_fixed_bytes(); chained_bytecode_hash = keccak256(&[chained_bytecode_hash, hash.to_vec()].concat()).to_vec(); } diff --git a/core/lib/multivm/src/utils/bytecode.rs b/core/lib/multivm/src/utils/bytecode.rs index c1937e992990..f5dee805864e 100644 --- a/core/lib/multivm/src/utils/bytecode.rs +++ b/core/lib/multivm/src/utils/bytecode.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; use zksync_types::{ + bytecode::{validate_bytecode, BytecodeHash, InvalidBytecodeError}, ethabi::{self, Token}, Address, H256, U256, }; -use zksync_utils::bytecode::{hash_bytecode, validate_bytecode, InvalidBytecodeError}; use crate::interface::CompressedBytecodeInfo; @@ -46,6 +46,15 @@ pub(crate) fn be_bytes_to_safe_address(bytes: &[u8]) -> Option
{ } } +pub(crate) fn bytecode_len_in_words(bytecode_hash: &H256) -> u16 { + let bytes = bytecode_hash.as_bytes(); + u16::from_be_bytes([bytes[2], bytes[3]]) +} + +pub(crate) fn bytecode_len_in_bytes(bytecode_hash: &H256) -> u32 { + u32::from(bytecode_len_in_words(bytecode_hash)) * 32 +} + #[derive(Debug, thiserror::Error)] pub(crate) enum FailedToCompressBytecodeError { #[error("Number of unique 8-bytes bytecode chunks exceed the limit of 2^16 - 1")] @@ -128,7 +137,10 @@ pub(crate) fn compress( } pub(crate) fn encode_call(bytecode: &CompressedBytecodeInfo) -> Vec { - let mut bytecode_hash = hash_bytecode(&bytecode.original).as_bytes().to_vec(); + let mut bytecode_hash = BytecodeHash::for_bytecode(&bytecode.original) + .value() + .as_bytes() + .to_vec(); let empty_cell = [0_u8; 32]; bytecode_hash.extend_from_slice(&empty_cell); diff --git a/core/lib/multivm/src/utils/mod.rs b/core/lib/multivm/src/utils/mod.rs index a55adb16c85a..4332c0327ff1 100644 --- a/core/lib/multivm/src/utils/mod.rs +++ b/core/lib/multivm/src/utils/mod.rs @@ -239,16 +239,16 @@ pub fn get_bootloader_encoding_space(version: VmVersion) -> u32 { VmVersion::Vm1_4_2 => crate::vm_1_4_2::constants::BOOTLOADER_TX_ENCODING_SPACE, VmVersion::Vm1_5_0SmallBootloaderMemory => { crate::vm_latest::constants::get_bootloader_tx_encoding_space( - crate::vm_latest::MultiVMSubversion::SmallBootloaderMemory, + crate::vm_latest::MultiVmSubversion::SmallBootloaderMemory, ) } VmVersion::Vm1_5_0IncreasedBootloaderMemory => { crate::vm_latest::constants::get_bootloader_tx_encoding_space( - crate::vm_latest::MultiVMSubversion::IncreasedBootloaderMemory, + crate::vm_latest::MultiVmSubversion::IncreasedBootloaderMemory, ) } VmVersion::VmGateway => crate::vm_latest::constants::get_bootloader_tx_encoding_space( - crate::vm_latest::MultiVMSubversion::Gateway, + crate::vm_latest::MultiVmSubversion::Gateway, ), } } @@ -394,16 +394,16 @@ pub fn get_used_bootloader_memory_bytes(version: VmVersion) -> usize { VmVersion::Vm1_4_2 => crate::vm_1_4_2::constants::USED_BOOTLOADER_MEMORY_BYTES, VmVersion::Vm1_5_0SmallBootloaderMemory => { crate::vm_latest::constants::get_used_bootloader_memory_bytes( - crate::vm_latest::MultiVMSubversion::SmallBootloaderMemory, + crate::vm_latest::MultiVmSubversion::SmallBootloaderMemory, ) } VmVersion::Vm1_5_0IncreasedBootloaderMemory => { crate::vm_latest::constants::get_used_bootloader_memory_bytes( - crate::vm_latest::MultiVMSubversion::IncreasedBootloaderMemory, + crate::vm_latest::MultiVmSubversion::IncreasedBootloaderMemory, ) } VmVersion::VmGateway => crate::vm_latest::constants::get_used_bootloader_memory_bytes( - crate::vm_latest::MultiVMSubversion::Gateway, + crate::vm_latest::MultiVmSubversion::Gateway, ), } } @@ -430,16 +430,16 @@ pub fn get_used_bootloader_memory_words(version: VmVersion) -> usize { VmVersion::Vm1_4_2 => crate::vm_1_4_2::constants::USED_BOOTLOADER_MEMORY_WORDS, VmVersion::Vm1_5_0SmallBootloaderMemory => { crate::vm_latest::constants::get_used_bootloader_memory_bytes( - crate::vm_latest::MultiVMSubversion::SmallBootloaderMemory, + crate::vm_latest::MultiVmSubversion::SmallBootloaderMemory, ) } VmVersion::Vm1_5_0IncreasedBootloaderMemory => { crate::vm_latest::constants::get_used_bootloader_memory_bytes( - crate::vm_latest::MultiVMSubversion::IncreasedBootloaderMemory, + crate::vm_latest::MultiVmSubversion::IncreasedBootloaderMemory, ) } VmVersion::VmGateway => crate::vm_latest::constants::get_used_bootloader_memory_bytes( - crate::vm_latest::MultiVMSubversion::Gateway, + crate::vm_latest::MultiVmSubversion::Gateway, ), } } diff --git a/core/lib/multivm/src/versions/shadow/mod.rs b/core/lib/multivm/src/versions/shadow/mod.rs index 42a0fbb1b8ba..01eeb3669f43 100644 --- a/core/lib/multivm/src/versions/shadow/mod.rs +++ b/core/lib/multivm/src/versions/shadow/mod.rs @@ -12,7 +12,6 @@ use zksync_types::{ block::L2BlockHasher, fee::Fee, AccountTreeId, Address, Execute, L1BatchNumber, L2BlockNumber, ProtocolVersionId, StorageKey, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{ @@ -207,7 +206,7 @@ where { let system_env = default_system_env(); let l1_batch_env = default_l1_batch(L1BatchNumber(1)); - let mut storage = InMemoryStorage::with_system_contracts(hash_bytecode); + let mut storage = InMemoryStorage::with_system_contracts(); let mut harness = Harness::new(&l1_batch_env); harness.setup_storage(&mut storage); @@ -231,7 +230,7 @@ fn sanity_check_harness_on_new_vm() { fn sanity_check_shadow_vm() { let system_env = default_system_env(); let l1_batch_env = default_l1_batch(L1BatchNumber(1)); - let mut storage = InMemoryStorage::with_system_contracts(hash_bytecode); + let mut storage = InMemoryStorage::with_system_contracts(); let mut harness = Harness::new(&l1_batch_env); harness.setup_storage(&mut storage); @@ -258,7 +257,7 @@ fn shadow_vm_basics() { pretty_assertions::assert_eq!(replayed_dump, dump); // Check that the VM executes identically when reading from the original storage and one restored from the dump. - let mut storage = InMemoryStorage::with_system_contracts(hash_bytecode); + let mut storage = InMemoryStorage::with_system_contracts(); harness.setup_storage(&mut storage); let storage = StorageView::new(storage).to_rc_ptr(); diff --git a/core/lib/multivm/src/versions/testonly/block_tip.rs b/core/lib/multivm/src/versions/testonly/block_tip.rs index 61678e01a443..f4655610afcb 100644 --- a/core/lib/multivm/src/versions/testonly/block_tip.rs +++ b/core/lib/multivm/src/versions/testonly/block_tip.rs @@ -5,10 +5,10 @@ use zksync_system_constants::{ CONTRACT_FORCE_DEPLOYER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, }; use zksync_types::{ - commitment::SerializeCommitment, fee_model::BatchFeeInput, get_code_key, - l2_to_l1_log::L2ToL1Log, u256_to_h256, writes::StateDiffRecord, Address, Execute, H256, U256, + bytecode::BytecodeHash, commitment::SerializeCommitment, fee_model::BatchFeeInput, + get_code_key, l2_to_l1_log::L2ToL1Log, u256_to_h256, writes::StateDiffRecord, Address, Execute, + H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use super::{ default_pubdata_builder, get_complex_upgrade_abi, get_empty_storage, read_complex_upgrade, @@ -72,7 +72,9 @@ fn populate_mimic_calls(data: L1MessengerTestData) -> Vec> { data: l1_messenger .function("requestBytecodeL1Publication") .unwrap() - .encode_input(&[Token::FixedBytes(hash_bytecode(bytecode).0.to_vec())]) + .encode_input(&[Token::FixedBytes( + BytecodeHash::for_bytecode(bytecode).value().0.to_vec(), + )]) .unwrap(), }); @@ -118,9 +120,12 @@ fn execute_test(test_data: L1MessengerTestData) -> TestStatistics // For this test we'll just put the bytecode onto the force deployer address storage.set_value( get_code_key(&CONTRACT_FORCE_DEPLOYER_ADDRESS), - hash_bytecode(&complex_upgrade_code), + BytecodeHash::for_bytecode(&complex_upgrade_code).value(), + ); + storage.store_factory_dep( + BytecodeHash::for_bytecode(&complex_upgrade_code).value(), + complex_upgrade_code, ); - storage.store_factory_dep(hash_bytecode(&complex_upgrade_code), complex_upgrade_code); // We are measuring computational cost, so prices for pubdata don't matter, while they artificially dilute // the gas limit diff --git a/core/lib/multivm/src/versions/testonly/code_oracle.rs b/core/lib/multivm/src/versions/testonly/code_oracle.rs index 6a1fcfb28df3..ace3b116b038 100644 --- a/core/lib/multivm/src/versions/testonly/code_oracle.rs +++ b/core/lib/multivm/src/versions/testonly/code_oracle.rs @@ -1,9 +1,8 @@ use ethabi::Token; use zksync_types::{ - get_known_code_key, h256_to_u256, u256_to_h256, web3::keccak256, Address, Execute, - StorageLogWithPreviousValue, U256, + bytecode::BytecodeHash, get_known_code_key, h256_to_u256, u256_to_h256, web3::keccak256, + Address, Execute, StorageLogWithPreviousValue, U256, }; -use zksync_utils::bytecode::hash_bytecode; use super::{ get_empty_storage, load_precompiles_contract, read_precompiles_contract, read_test_contract, @@ -25,7 +24,7 @@ pub(crate) fn test_code_oracle() { // Filling the zkevm bytecode let normal_zkevm_bytecode = read_test_contract(); - let normal_zkevm_bytecode_hash = hash_bytecode(&normal_zkevm_bytecode); + let normal_zkevm_bytecode_hash = BytecodeHash::for_bytecode(&normal_zkevm_bytecode).value(); let normal_zkevm_bytecode_keccak_hash = keccak256(&normal_zkevm_bytecode); let mut storage = get_empty_storage(); storage.set_value( @@ -115,7 +114,7 @@ pub(crate) fn test_code_oracle_big_bytecode() { let precompile_contract_bytecode = read_precompiles_contract(); let big_zkevm_bytecode = generate_large_bytecode(); - let big_zkevm_bytecode_hash = hash_bytecode(&big_zkevm_bytecode); + let big_zkevm_bytecode_hash = BytecodeHash::for_bytecode(&big_zkevm_bytecode).value(); let big_zkevm_bytecode_keccak_hash = keccak256(&big_zkevm_bytecode); let mut storage = get_empty_storage(); @@ -173,7 +172,7 @@ pub(crate) fn test_refunds_in_code_oracle() { let precompile_contract_bytecode = read_precompiles_contract(); let normal_zkevm_bytecode = read_test_contract(); - let normal_zkevm_bytecode_hash = hash_bytecode(&normal_zkevm_bytecode); + let normal_zkevm_bytecode_hash = BytecodeHash::for_bytecode(&normal_zkevm_bytecode).value(); let normal_zkevm_bytecode_keccak_hash = keccak256(&normal_zkevm_bytecode); let mut storage = get_empty_storage(); storage.set_value( diff --git a/core/lib/multivm/src/versions/testonly/evm_emulator.rs b/core/lib/multivm/src/versions/testonly/evm_emulator.rs index 1e7e136e4b99..8442df86f93c 100644 --- a/core/lib/multivm/src/versions/testonly/evm_emulator.rs +++ b/core/lib/multivm/src/versions/testonly/evm_emulator.rs @@ -9,11 +9,11 @@ use zksync_system_constants::{ }; use zksync_test_account::TxType; use zksync_types::{ + bytecode::BytecodeHash, get_code_key, get_known_code_key, h256_to_u256, utils::{key_for_eth_balance, storage_key_for_eth_balance}, AccountTreeId, Address, Execute, StorageKey, H256, U256, }; -use zksync_utils::bytecode::{hash_bytecode, hash_evm_bytecode}; use super::{default_system_env, TestedVm, VmTester, VmTesterBuilder}; use crate::interface::{ @@ -30,9 +30,9 @@ const INCREMENTING_CONTRACT_PATH: &str = "etc/contracts-test-data/artifacts-zk/c fn override_system_contracts(storage: &mut InMemoryStorage) { let mock_deployer = read_bytecode(MOCK_DEPLOYER_PATH); - let mock_deployer_hash = hash_bytecode(&mock_deployer); + let mock_deployer_hash = BytecodeHash::for_bytecode(&mock_deployer).value(); let mock_known_code_storage = read_bytecode(MOCK_KNOWN_CODE_STORAGE_PATH); - let mock_known_code_storage_hash = hash_bytecode(&mock_known_code_storage); + let mock_known_code_storage_hash = BytecodeHash::for_bytecode(&mock_known_code_storage).value(); storage.set_value(get_code_key(&CONTRACT_DEPLOYER_ADDRESS), mock_deployer_hash); storage.set_value( @@ -62,7 +62,7 @@ impl EvmTestBuilder { fn new(deploy_emulator: bool, evm_contract_address: Address) -> Self { Self { deploy_emulator, - storage: InMemoryStorage::with_system_contracts(hash_bytecode), + storage: InMemoryStorage::with_system_contracts(), evm_contract_addresses: vec![evm_contract_address], } } @@ -83,7 +83,7 @@ impl EvmTestBuilder { let mut system_env = default_system_env(); if self.deploy_emulator { let evm_bytecode: Vec<_> = (0..32).collect(); - let evm_bytecode_hash = hash_evm_bytecode(&evm_bytecode); + let evm_bytecode_hash = BytecodeHash::for_evm_bytecode(&evm_bytecode).value(); storage.set_value( get_known_code_key(&evm_bytecode_hash), H256::from_low_u64_be(1), @@ -93,11 +93,11 @@ impl EvmTestBuilder { } system_env.base_system_smart_contracts.evm_emulator = Some(SystemContractCode { - hash: hash_bytecode(&mock_emulator), + hash: BytecodeHash::for_bytecode(&mock_emulator).value(), code: mock_emulator, }); } else { - let emulator_hash = hash_bytecode(&mock_emulator); + let emulator_hash = BytecodeHash::for_bytecode(&mock_emulator).value(); storage.set_value(get_known_code_key(&emulator_hash), H256::from_low_u64_be(1)); storage.store_factory_dep(emulator_hash, mock_emulator); @@ -121,7 +121,7 @@ impl EvmTestBuilder { } pub(crate) fn test_tracing_evm_contract_deployment() { - let mut storage = InMemoryStorage::with_system_contracts(hash_bytecode); + let mut storage = InMemoryStorage::with_system_contracts(); override_system_contracts(&mut storage); let mut system_env = default_system_env(); @@ -138,7 +138,7 @@ pub(crate) fn test_tracing_evm_contract_deployment() { let args = [Token::Bytes((0..32).collect())]; let evm_bytecode = ethabi::encode(&args); - let expected_bytecode_hash = hash_evm_bytecode(&evm_bytecode); + let expected_bytecode_hash = BytecodeHash::for_evm_bytecode(&evm_bytecode).value(); let execute = Execute::for_deploy(expected_bytecode_hash, vec![0; 32], &args); let deploy_tx = account.get_l2_tx_for_execute(execute, None); let (_, vm_result) = vm @@ -155,7 +155,7 @@ pub(crate) fn test_tracing_evm_contract_deployment() { // "Deploy" a bytecode in another transaction and check that the first tx doesn't interfere with the returned `dynamic_factory_deps`. let args = [Token::Bytes((0..32).rev().collect())]; let evm_bytecode = ethabi::encode(&args); - let expected_bytecode_hash = hash_evm_bytecode(&evm_bytecode); + let expected_bytecode_hash = BytecodeHash::for_evm_bytecode(&evm_bytecode).value(); let execute = Execute::for_deploy(expected_bytecode_hash, vec![0; 32], &args); let deploy_tx = account.get_l2_tx_for_execute(execute, None); let (_, vm_result) = vm @@ -334,7 +334,7 @@ pub(crate) fn test_mock_emulator_with_deployment(revert: bool) { let mock_emulator_abi = load_contract(MOCK_EMULATOR_PATH); let new_evm_bytecode = vec![0xfe; 96]; - let new_evm_bytecode_hash = hash_evm_bytecode(&new_evm_bytecode); + let new_evm_bytecode_hash = BytecodeHash::for_evm_bytecode(&new_evm_bytecode).value(); let test_fn = mock_emulator_abi.function("testDeploymentAndCall").unwrap(); let test_tx = account.get_l2_tx_for_execute( @@ -412,7 +412,7 @@ pub(crate) fn test_mock_emulator_with_recursive_deployment() { let bytecodes: HashMap<_, _> = (0_u8..10) .map(|byte| { let bytecode = vec![byte; 32]; - (hash_evm_bytecode(&bytecode), bytecode) + (BytecodeHash::for_evm_bytecode(&bytecode).value(), bytecode) }) .collect(); let test_fn = mock_emulator_abi @@ -458,7 +458,7 @@ fn test_mock_emulator_with_partial_reverts_and_rng(rng: &mut impl let all_bytecodes: HashMap<_, _> = (0_u8..10) .map(|_| { let bytecode = vec![rng.gen(); 32]; - (hash_evm_bytecode(&bytecode), bytecode) + (BytecodeHash::for_evm_bytecode(&bytecode).value(), bytecode) }) .collect(); let should_revert: Vec<_> = (0..10).map(|_| rng.gen::()).collect(); diff --git a/core/lib/multivm/src/versions/testonly/get_used_contracts.rs b/core/lib/multivm/src/versions/testonly/get_used_contracts.rs index fa6470b44c47..d5268d9c63ff 100644 --- a/core/lib/multivm/src/versions/testonly/get_used_contracts.rs +++ b/core/lib/multivm/src/versions/testonly/get_used_contracts.rs @@ -5,8 +5,9 @@ use ethabi::Token; use zk_evm_1_3_1::zkevm_opcode_defs::decoding::{EncodingModeProduction, VmEncodingMode}; use zksync_system_constants::CONTRACT_DEPLOYER_ADDRESS; use zksync_test_account::{Account, TxType}; -use zksync_types::{h256_to_u256, AccountTreeId, Address, Execute, StorageKey, H256, U256}; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{ + bytecode::BytecodeHash, h256_to_u256, AccountTreeId, Address, Execute, StorageKey, H256, U256, +}; use super::{ read_proxy_counter_contract, read_test_contract, @@ -76,8 +77,7 @@ pub(crate) fn test_get_used_contracts() { assert!(res2.result.is_failed()); for factory_dep in tx2.execute.factory_deps { - let hash = hash_bytecode(&factory_dep); - let hash_to_u256 = h256_to_u256(hash); + let hash_to_u256 = BytecodeHash::for_bytecode(&factory_dep).value_u256(); assert!(vm.vm.known_bytecode_hashes().contains(&hash_to_u256)); assert!(!vm.vm.decommitted_hashes().contains(&hash_to_u256)); } @@ -105,7 +105,7 @@ fn execute_proxy_counter( gas: u32, ) -> (VmTester, ProxyCounterData, VmExecutionResultAndLogs) { let counter_bytecode = inflated_counter_bytecode(); - let counter_bytecode_hash = h256_to_u256(hash_bytecode(&counter_bytecode)); + let counter_bytecode_hash = BytecodeHash::for_bytecode(&counter_bytecode).value_u256(); let counter_address = Address::repeat_byte(0x23); let mut vm = VmTesterBuilder::new() diff --git a/core/lib/multivm/src/versions/testonly/mod.rs b/core/lib/multivm/src/versions/testonly/mod.rs index 3377a49064f8..68044fe8228c 100644 --- a/core/lib/multivm/src/versions/testonly/mod.rs +++ b/core/lib/multivm/src/versions/testonly/mod.rs @@ -18,11 +18,10 @@ use zksync_contracts::{ SystemContractCode, }; use zksync_types::{ - block::L2BlockHasher, fee_model::BatchFeeInput, get_code_key, get_is_account_key, h256_to_u256, - u256_to_h256, utils::storage_key_for_eth_balance, Address, L1BatchNumber, L2BlockNumber, - L2ChainId, ProtocolVersionId, U256, + block::L2BlockHasher, bytecode::BytecodeHash, fee_model::BatchFeeInput, get_code_key, + get_is_account_key, h256_to_u256, u256_to_h256, utils::storage_key_for_eth_balance, Address, + L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, U256, }; -use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::{ pubdata::PubdataBuilder, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, }; @@ -62,7 +61,7 @@ static BASE_SYSTEM_CONTRACTS: Lazy = Lazy::new(BaseSystemContracts::load_from_disk); fn get_empty_storage() -> InMemoryStorage { - InMemoryStorage::with_system_contracts(hash_bytecode) + InMemoryStorage::with_system_contracts() } pub(crate) fn read_test_contract() -> Vec { @@ -131,7 +130,7 @@ pub(crate) fn read_simple_transfer_contract() -> Vec { pub(crate) fn get_bootloader(test: &str) -> SystemContractCode { let bootloader_code = read_bootloader_code(test); - let bootloader_hash = hash_bytecode(&bootloader_code); + let bootloader_hash = BytecodeHash::for_bytecode(&bootloader_code).value(); SystemContractCode { code: bootloader_code, hash: bootloader_hash, @@ -223,12 +222,13 @@ impl ContractToDeploy { pub fn insert(&self, storage: &mut InMemoryStorage) { let deployer_code_key = get_code_key(&self.address); - storage.set_value(deployer_code_key, hash_bytecode(&self.bytecode)); + let bytecode_hash = BytecodeHash::for_bytecode(&self.bytecode).value(); + storage.set_value(deployer_code_key, bytecode_hash); if self.is_account { let is_account_key = get_is_account_key(&self.address); storage.set_value(is_account_key, u256_to_h256(1_u32.into())); } - storage.store_factory_dep(hash_bytecode(&self.bytecode), self.bytecode.clone()); + storage.store_factory_dep(bytecode_hash, self.bytecode.clone()); if self.is_funded { make_address_rich(storage, self.address); diff --git a/core/lib/multivm/src/versions/testonly/upgrade.rs b/core/lib/multivm/src/versions/testonly/upgrade.rs index 3fb6257f7070..b33862afe4b7 100644 --- a/core/lib/multivm/src/versions/testonly/upgrade.rs +++ b/core/lib/multivm/src/versions/testonly/upgrade.rs @@ -1,6 +1,7 @@ use zksync_contracts::{deployer_contract, load_sys_contract, read_bytecode}; use zksync_test_account::TxType; use zksync_types::{ + bytecode::BytecodeHash, ethabi::{Contract, Token}, get_code_key, get_known_code_key, h256_to_u256, protocol_upgrade::ProtocolUpgradeTxCommonData, @@ -8,7 +9,6 @@ use zksync_types::{ COMPLEX_UPGRADER_ADDRESS, CONTRACT_DEPLOYER_ADDRESS, CONTRACT_FORCE_DEPLOYER_ADDRESS, H256, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE, U256, }; -use zksync_utils::bytecode::hash_bytecode; use super::{ get_complex_upgrade_abi, get_empty_storage, read_complex_upgrade, read_test_contract, @@ -23,7 +23,7 @@ use crate::interface::{ /// - If present, this transaction must be the first one in block pub(crate) fn test_protocol_upgrade_is_first() { let mut storage = get_empty_storage(); - let bytecode_hash = hash_bytecode(&read_test_contract()); + let bytecode_hash = BytecodeHash::for_bytecode(&read_test_contract()).value(); storage.set_value(get_known_code_key(&bytecode_hash), u256_to_h256(1.into())); let mut vm = VmTesterBuilder::new() @@ -111,7 +111,7 @@ pub(crate) fn test_protocol_upgrade_is_first() { /// In this test we try to test how force deployments could be done via protocol upgrade transactions. pub(crate) fn test_force_deploy_upgrade() { let mut storage = get_empty_storage(); - let bytecode_hash = hash_bytecode(&read_test_contract()); + let bytecode_hash = BytecodeHash::for_bytecode(&read_test_contract()).value(); let known_code_key = get_known_code_key(&bytecode_hash); // It is generally expected that all the keys will be set as known prior to the protocol upgrade. storage.set_value(known_code_key, u256_to_h256(1.into())); @@ -156,8 +156,8 @@ pub(crate) fn test_force_deploy_upgrade() { /// Here we show how the work with the complex upgrader could be done. pub(crate) fn test_complex_upgrader() { let mut storage = get_empty_storage(); - let bytecode_hash = hash_bytecode(&read_complex_upgrade()); - let msg_sender_test_hash = hash_bytecode(&read_msg_sender_test()); + let bytecode_hash = BytecodeHash::for_bytecode(&read_complex_upgrade()).value(); + let msg_sender_test_hash = BytecodeHash::for_bytecode(&read_msg_sender_test()).value(); // Let's assume that the bytecode for the implementation of the complex upgrade // is already deployed in some address in user space let upgrade_impl = Address::repeat_byte(1); diff --git a/core/lib/multivm/src/versions/vm_1_3_2/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_1_3_2/oracles/decommitter.rs index 07fcdb0f522f..779fc126e72c 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/oracles/decommitter.rs @@ -7,12 +7,11 @@ use zk_evm_1_3_3::{ }, }; use zksync_types::{u256_to_h256, U256}; -use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{StoragePtr, WriteStorage}, - utils::bytecode::bytes_to_be_words, + utils::bytecode::{bytecode_len_in_words, bytes_to_be_words}, vm_1_3_2::history_recorder::{HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory}, }; diff --git a/core/lib/multivm/src/versions/vm_1_3_2/pubdata_utils.rs b/core/lib/multivm/src/versions/vm_1_3_2/pubdata_utils.rs index d88ee70991bc..3c10bd8c48be 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/pubdata_utils.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/pubdata_utils.rs @@ -3,10 +3,10 @@ use std::collections::HashMap; use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; use zk_evm_1_3_3::aux_structures::Timestamp; use zksync_types::{StorageKey, PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; -use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{storage::WriteStorage, VmEvent}, + utils::bytecode::bytecode_len_in_bytes, vm_1_3_2::{history_recorder::HistoryMode, oracles::storage::storage_key_of_log, VmInstance}, }; @@ -30,9 +30,7 @@ impl VmInstance { let published_bytecode_bytes: u32 = VmEvent::extract_published_bytecodes(&events) .iter() - .map(|bytecodehash| { - bytecode_len_in_bytes(*bytecodehash) as u32 + PUBLISH_BYTECODE_OVERHEAD - }) + .map(|bytecode_hash| bytecode_len_in_bytes(bytecode_hash) + PUBLISH_BYTECODE_OVERHEAD) .sum(); storage_writes_pubdata_published diff --git a/core/lib/multivm/src/versions/vm_1_3_2/test_utils.rs b/core/lib/multivm/src/versions/vm_1_3_2/test_utils.rs index 42106bbdfa22..ac6ce7fcdfcf 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/test_utils.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/test_utils.rs @@ -13,12 +13,12 @@ use zk_evm_1_3_3::{aux_structures::Timestamp, vm_state::VmLocalState}; use zksync_contracts::deployer_contract; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{Address, Token}, h256_to_address, u256_to_h256, web3::keccak256, Execute, Nonce, StorageKey, StorageValue, CONTRACT_DEPLOYER_ADDRESS, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::interface::storage::WriteStorage; /// The tests here help us with the testing the VM @@ -145,7 +145,7 @@ pub fn get_create_execute(code: &[u8], calldata: &[u8]) -> Execute { let params = [ Token::FixedBytes(vec![0u8; 32]), - Token::FixedBytes(hash_bytecode(code).0.to_vec()), + Token::FixedBytes(BytecodeHash::for_bytecode(code).value().0.to_vec()), Token::Bytes(calldata.to_vec()), ]; let calldata = contract_function diff --git a/core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs b/core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs index e63b6ec5a87d..c2dfe97ed076 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs @@ -1,6 +1,8 @@ use zk_evm_1_3_3::zkevm_opcode_defs::system_params::MAX_TX_ERGS_LIMIT; use zksync_types::{ - address_to_h256, ceil_div_u256, + address_to_h256, + bytecode::BytecodeHash, + ceil_div_u256, ethabi::{encode, Address, Token}, fee::encoding_len, h256_to_u256, @@ -8,7 +10,6 @@ use zksync_types::{ l2::TransactionType, ExecuteTransactionCommon, Transaction, MAX_L2_TX_GAS_LIMIT, U256, }; -use zksync_utils::bytecode::hash_bytecode; use super::vm_with_bootloader::MAX_TXS_IN_BLOCK; use crate::{ @@ -194,7 +195,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } diff --git a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs index 45b8a09c5a34..05902b736fbd 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs @@ -1,7 +1,6 @@ use std::{collections::HashSet, rc::Rc}; -use zksync_types::{h256_to_u256, Transaction}; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, h256_to_u256, Transaction}; use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ @@ -119,7 +118,7 @@ impl VmInterface for Vm { let mut deps_hashes = HashSet::with_capacity(deps.len()); let mut bytecode_hashes = vec![]; let filtered_deps = deps.iter().filter_map(|bytecode| { - let bytecode_hash = hash_bytecode(bytecode); + let bytecode_hash = BytecodeHash::for_bytecode(bytecode).value(); let is_known = !deps_hashes.insert(bytecode_hash) || self.vm.is_bytecode_known(&bytecode_hash); diff --git a/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs b/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs index eee1baa59d60..ca9ba097d472 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs @@ -15,10 +15,10 @@ use zk_evm_1_3_3::{ use zksync_contracts::BaseSystemContracts; use zksync_system_constants::MAX_L2_TX_GAS_LIMIT; use zksync_types::{ - address_to_u256, fee_model::L1PeggedBatchFeeModelInput, h256_to_u256, l1::is_l1_tx_type, - Address, Transaction, BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, + address_to_u256, bytecode::BytecodeHash, fee_model::L1PeggedBatchFeeModelInput, h256_to_u256, + l1::is_l1_tx_type, Address, Transaction, BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, + MAX_NEW_FACTORY_DEPS, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{storage::WriteStorage, CompressedBytecodeInfo, L1BatchEnv}, @@ -518,7 +518,7 @@ pub fn push_raw_transaction_to_bootloader_memory PrimitiveValue { } } -// FIXME: &[u8] pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { - let bytecode_hash = hash_bytecode(&bytecode); - let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value_u256(); let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs index c8adcf116d74..0278e239522b 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs @@ -1,6 +1,5 @@ use itertools::Itertools; -use zksync_types::U256; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, U256}; use crate::{ interface::{ @@ -25,15 +24,14 @@ impl Vm { .storage .get_ptr() .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) + .is_bytecode_known(&BytecodeHash::for_bytecode(&info.original).value()) }) } } /// Converts bytecode to tokens and hashes it. pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { - let bytecode_hash = hash_bytecode(&bytecode); - let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value_u256(); let bytecode_words = bytecode::bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } @@ -47,7 +45,11 @@ pub(crate) fn compress_bytecodes( .enumerate() .sorted_by_key(|(_idx, dep)| *dep) .dedup_by(|x, y| x.1 == y.1) - .filter(|(_idx, dep)| !storage.borrow_mut().is_bytecode_known(&hash_bytecode(dep))) + .filter(|(_idx, dep)| { + !storage + .borrow_mut() + .is_bytecode_known(&BytecodeHash::for_bytecode(dep).value()) + }) .sorted_by_key(|(idx, _dep)| *idx) .filter_map(|(_idx, dep)| bytecode::compress(dep.clone()).ok()) .collect() diff --git a/core/lib/multivm/src/versions/vm_1_4_1/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_1_4_1/old_vm/oracles/decommitter.rs index e4df1e4c7fcd..0fe3efa30b68 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/old_vm/oracles/decommitter.rs @@ -7,12 +7,11 @@ use zk_evm_1_4_1::{ }, }; use zksync_types::{u256_to_h256, U256}; -use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, - utils::bytecode::bytes_to_be_words, + utils::bytecode::{bytecode_len_in_words, bytes_to_be_words}, vm_1_4_1::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, diff --git a/core/lib/multivm/src/versions/vm_1_4_1/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_1_4_1/tracers/refunds.rs index ab883d9bcbd2..dc945e183a8f 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/tracers/refunds.rs @@ -11,7 +11,6 @@ use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS} use zksync_types::{ ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, H256, U256, }; -use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ @@ -20,6 +19,7 @@ use crate::{ L1BatchEnv, Refunds, VmEvent, }, tracers::dynamic::vm_1_4_1::DynTracer, + utils::bytecode::bytecode_len_in_bytes, vm_1_4_1::{ bootloader_state::BootloaderState, constants::{BOOTLOADER_HEAP_PAGE, OPERATOR_REFUNDS_OFFSET, TX_GAS_LIMIT_OFFSET}, @@ -350,7 +350,7 @@ pub(crate) fn pubdata_published( let published_bytecode_bytes: u32 = VmEvent::extract_published_bytecodes(&events) .iter() - .map(|bytecodehash| bytecode_len_in_bytes(*bytecodehash) as u32 + PUBLISH_BYTECODE_OVERHEAD) + .map(|bytecode_hash| bytecode_len_in_bytes(bytecode_hash) + PUBLISH_BYTECODE_OVERHEAD) .sum(); storage_writes_pubdata_published diff --git a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/transaction_data.rs index 872ab3d05dd5..af9a93f647a2 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/transaction_data.rs @@ -2,6 +2,7 @@ use std::convert::TryInto; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, h256_to_u256, @@ -11,7 +12,6 @@ use zksync_types::{ web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ utils::bytecode::bytes_to_be_words, @@ -195,7 +195,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } diff --git a/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs index 2a6ef1d1ab4d..f81deff48c25 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs @@ -1,6 +1,5 @@ use itertools::Itertools; -use zksync_types::U256; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, U256}; use crate::{ interface::{ @@ -25,15 +24,14 @@ impl Vm { .storage .get_ptr() .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) + .is_bytecode_known(&BytecodeHash::for_bytecode(&info.original).value()) }) } } /// Converts bytecode to tokens and hashes it. pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { - let bytecode_hash = hash_bytecode(&bytecode); - let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value_u256(); let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } @@ -47,7 +45,11 @@ pub(crate) fn compress_bytecodes( .enumerate() .sorted_by_key(|(_idx, dep)| *dep) .dedup_by(|x, y| x.1 == y.1) - .filter(|(_idx, dep)| !storage.borrow_mut().is_bytecode_known(&hash_bytecode(dep))) + .filter(|(_idx, dep)| { + !storage + .borrow_mut() + .is_bytecode_known(&BytecodeHash::for_bytecode(dep).value()) + }) .sorted_by_key(|(idx, _dep)| *idx) .filter_map(|(_idx, dep)| bytecode::compress(dep.clone()).ok()) .collect() diff --git a/core/lib/multivm/src/versions/vm_1_4_2/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_1_4_2/old_vm/oracles/decommitter.rs index 3d0e9bda8030..9122a10c9266 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/old_vm/oracles/decommitter.rs @@ -7,12 +7,11 @@ use zk_evm_1_4_1::{ }, }; use zksync_types::{u256_to_h256, U256}; -use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, - utils::bytecode::bytes_to_be_words, + utils::bytecode::{bytecode_len_in_words, bytes_to_be_words}, vm_1_4_2::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, diff --git a/core/lib/multivm/src/versions/vm_1_4_2/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_1_4_2/tracers/refunds.rs index 8cfcd8c327e4..324cad02b4eb 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/tracers/refunds.rs @@ -11,7 +11,6 @@ use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS} use zksync_types::{ ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, H256, U256, }; -use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ @@ -20,6 +19,7 @@ use crate::{ L1BatchEnv, Refunds, VmEvent, }, tracers::dynamic::vm_1_4_1::DynTracer, + utils::bytecode::bytecode_len_in_bytes, vm_1_4_2::{ bootloader_state::BootloaderState, constants::{BOOTLOADER_HEAP_PAGE, OPERATOR_REFUNDS_OFFSET, TX_GAS_LIMIT_OFFSET}, @@ -350,7 +350,7 @@ pub(crate) fn pubdata_published( let published_bytecode_bytes: u32 = VmEvent::extract_published_bytecodes(&events) .iter() - .map(|bytecodehash| bytecode_len_in_bytes(*bytecodehash) as u32 + PUBLISH_BYTECODE_OVERHEAD) + .map(|bytecode_hash| bytecode_len_in_bytes(bytecode_hash) + PUBLISH_BYTECODE_OVERHEAD) .sum(); storage_writes_pubdata_published diff --git a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/transaction_data.rs index 693690e3b42e..e0f113f8a7ff 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/transaction_data.rs @@ -2,6 +2,7 @@ use std::convert::TryInto; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, h256_to_u256, @@ -11,7 +12,6 @@ use zksync_types::{ web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ utils::bytecode::bytes_to_be_words, @@ -195,7 +195,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs index 38d5b40af7e4..42507a589e50 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs @@ -1,6 +1,5 @@ use itertools::Itertools; -use zksync_types::U256; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, U256}; use crate::{ interface::{ @@ -25,15 +24,14 @@ impl Vm { .storage .get_ptr() .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) + .is_bytecode_known(&BytecodeHash::for_bytecode(&info.original).value()) }) } } /// Converts bytecode to tokens and hashes it. pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { - let bytecode_hash = hash_bytecode(&bytecode); - let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value_u256(); let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } @@ -47,7 +45,11 @@ pub(crate) fn compress_bytecodes( .enumerate() .sorted_by_key(|(_idx, dep)| *dep) .dedup_by(|x, y| x.1 == y.1) - .filter(|(_idx, dep)| !storage.borrow_mut().is_bytecode_known(&hash_bytecode(dep))) + .filter(|(_idx, dep)| { + !storage + .borrow_mut() + .is_bytecode_known(&BytecodeHash::for_bytecode(dep).value()) + }) .sorted_by_key(|(idx, _dep)| *idx) .filter_map(|(_idx, dep)| bytecode::compress(dep.clone()).ok()) .collect() diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/oracles/decommitter.rs index b61560afe39d..804bd7179781 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/oracles/decommitter.rs @@ -7,12 +7,11 @@ use zk_evm_1_4_0::{ }, }; use zksync_types::{u256_to_h256, U256}; -use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, - utils::bytecode::bytes_to_be_words, + utils::bytecode::{bytecode_len_in_words, bytes_to_be_words}, vm_boojum_integration::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/refunds.rs index 0d944724afd2..682cbda5252a 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/refunds.rs @@ -8,7 +8,6 @@ use zk_evm_1_4_0::{ }; use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; use zksync_types::{ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, U256}; -use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ @@ -17,6 +16,7 @@ use crate::{ L1BatchEnv, Refunds, VmEvent, }, tracers::dynamic::vm_1_4_0::DynTracer, + utils::bytecode::bytecode_len_in_bytes, vm_boojum_integration::{ bootloader_state::BootloaderState, constants::{BOOTLOADER_HEAP_PAGE, OPERATOR_REFUNDS_OFFSET, TX_GAS_LIMIT_OFFSET}, @@ -339,7 +339,7 @@ pub(crate) fn pubdata_published( let published_bytecode_bytes: u32 = VmEvent::extract_published_bytecodes(&events) .iter() - .map(|bytecodehash| bytecode_len_in_bytes(*bytecodehash) as u32 + PUBLISH_BYTECODE_OVERHEAD) + .map(|bytecode_hash| bytecode_len_in_bytes(bytecode_hash) + PUBLISH_BYTECODE_OVERHEAD) .sum(); storage_writes_pubdata_published diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/transaction_data.rs index 774d2061beb2..9011fa486da2 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/transaction_data.rs @@ -2,6 +2,7 @@ use std::convert::TryInto; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, h256_to_u256, @@ -11,7 +12,6 @@ use zksync_types::{ web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ utils::bytecode::bytes_to_be_words, @@ -195,7 +195,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } 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 index 15b4daf02a77..e104eba6ef4f 100644 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_fast/bootloader_state/state.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering; use once_cell::sync::OnceCell; -use zksync_types::{L2ChainId, U256}; +use zksync_types::{L2ChainId, ProtocolVersionId, U256}; use super::{ l2_block::BootloaderL2Block, @@ -10,8 +10,11 @@ use super::{ BootloaderStateSnapshot, }; use crate::{ - interface::{BootloaderMemory, CompressedBytecodeInfo, L2BlockEnv, TxExecutionMode}, - versions::vm_fast::{pubdata::PubdataInput, transaction_data::TransactionData}, + interface::{ + pubdata::{PubdataBuilder, PubdataInput}, + BootloaderMemory, CompressedBytecodeInfo, L2BlockEnv, TxExecutionMode, + }, + versions::vm_fast::transaction_data::TransactionData, vm_latest::{constants::TX_DESCRIPTION_OFFSET, utils::l2_blocks::assert_next_block}, }; @@ -42,6 +45,8 @@ pub struct BootloaderState { 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, } impl BootloaderState { @@ -49,6 +54,7 @@ impl BootloaderState { execution_mode: TxExecutionMode, initial_memory: BootloaderMemory, first_l2_block: L2BlockEnv, + protocol_version: ProtocolVersionId, ) -> Self { let l2_block = BootloaderL2Block::new(first_l2_block, 0); Self { @@ -59,6 +65,7 @@ impl BootloaderState { execution_mode, free_tx_offset: 0, pubdata_information: Default::default(), + protocol_version, } } @@ -139,12 +146,23 @@ impl BootloaderState { .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) -> BootloaderMemory { + 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; @@ -172,11 +190,15 @@ impl BootloaderState { let pubdata_information = self .pubdata_information - .clone() - .into_inner() + .get() .expect("Empty pubdata information"); - apply_pubdata_to_memory(&mut initial_memory, pubdata_information); + apply_pubdata_to_memory( + &mut initial_memory, + pubdata_builder, + pubdata_information, + self.protocol_version, + ); initial_memory } 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 index 838c2d6ba60f..9eb55d794235 100644 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_fast/bootloader_state/utils.rs @@ -1,10 +1,12 @@ -use zksync_types::{ethabi, h256_to_u256, U256}; +use zksync_types::{ethabi, h256_to_u256, ProtocolVersionId, U256}; use super::{l2_block::BootloaderL2Block, tx::BootloaderTx}; use crate::{ - interface::{BootloaderMemory, CompressedBytecodeInfo, TxExecutionMode}, + interface::{ + pubdata::{PubdataBuilder, PubdataInput}, + BootloaderMemory, CompressedBytecodeInfo, TxExecutionMode, + }, utils::bytecode, - versions::vm_fast::pubdata::PubdataInput, vm_latest::constants::{ BOOTLOADER_TX_DESCRIPTION_OFFSET, BOOTLOADER_TX_DESCRIPTION_SIZE, COMPRESSED_BYTECODES_OFFSET, OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_OFFSET, @@ -118,26 +120,54 @@ fn apply_l2_block_inner( ]) } +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_information: PubdataInput, + pubdata_builder: &dyn PubdataBuilder, + pubdata_information: &PubdataInput, + protocol_version: ProtocolVersionId, ) { - // 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 = OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_OFFSET + 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_information.build_pubdata(true), - )])[32..] - .to_vec(); - - assert!( - pubdata.len() / 32 <= OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS - 2, - "The encoded pubdata is too big" - ); + let (l1_messenger_pubdata_start_slot, pubdata) = if protocol_version.is_pre_gateway() { + // 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 = OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_OFFSET + 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) + } else { + // 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 = OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_OFFSET + 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) diff --git a/core/lib/multivm/src/versions/vm_fast/bytecode.rs b/core/lib/multivm/src/versions/vm_fast/bytecode.rs index abbd4461c25e..4dc52951c16c 100644 --- a/core/lib/multivm/src/versions/vm_fast/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_fast/bytecode.rs @@ -1,6 +1,5 @@ use itertools::Itertools; -use zksync_types::{h256_to_u256, H256}; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, h256_to_u256, H256}; use super::Vm; use crate::{ @@ -15,7 +14,7 @@ impl Vm { .get_last_tx_compressed_bytecodes() .iter() .any(|info| { - let hash_bytecode = hash_bytecode(&info.original); + let hash_bytecode = BytecodeHash::for_bytecode(&info.original).value(); let is_bytecode_known = self.world.storage.is_bytecode_known(&hash_bytecode); let is_bytecode_known_cache = self @@ -36,7 +35,7 @@ pub(crate) fn compress_bytecodes( .enumerate() .sorted_by_key(|(_idx, dep)| *dep) .dedup_by(|x, y| x.1 == y.1) - .filter(|(_idx, dep)| !is_bytecode_known(hash_bytecode(dep))) + .filter(|(_idx, dep)| !is_bytecode_known(BytecodeHash::for_bytecode(dep).value())) .sorted_by_key(|(idx, _dep)| *idx) .filter_map(|(_idx, dep)| bytecode::compress(dep.clone()).ok()) .collect() diff --git a/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs b/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs index fb619fa3e5ff..c443c99ccf9a 100644 --- a/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs +++ b/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs @@ -3,8 +3,7 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; use zksync_system_constants::{CONTRACT_DEPLOYER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS}; -use zksync_types::{h256_to_u256, U256}; -use zksync_utils::bytecode::hash_evm_bytecode; +use zksync_types::{bytecode::BytecodeHash, U256}; use zksync_vm2::interface::{ CallframeInterface, CallingMode, GlobalStateInterface, Opcode, OpcodeType, ShouldStop, Tracer, }; @@ -66,7 +65,8 @@ impl EvmDeployTracer { Ok(decoded) => { // `unwrap`s should be safe since the function signature is checked above. let published_bytecode = decoded.into_iter().next().unwrap().into_bytes().unwrap(); - let bytecode_hash = h256_to_u256(hash_evm_bytecode(&published_bytecode)); + let bytecode_hash = + BytecodeHash::for_evm_bytecode(&published_bytecode).value_u256(); self.bytecodes.insert(bytecode_hash, published_bytecode); } Err(err) => tracing::error!("Unable to decode `publishEVMBytecode` call: {err}"), diff --git a/core/lib/multivm/src/versions/vm_fast/mod.rs b/core/lib/multivm/src/versions/vm_fast/mod.rs index de6e7bd4ef6a..840653b63b08 100644 --- a/core/lib/multivm/src/versions/vm_fast/mod.rs +++ b/core/lib/multivm/src/versions/vm_fast/mod.rs @@ -1,5 +1,6 @@ pub use zksync_vm2::interface; +pub(crate) use self::version::FastVmVersion; pub use self::vm::Vm; mod bootloader_state; @@ -10,10 +11,10 @@ mod evm_deploy_tracer; mod glue; mod hook; mod initial_bootloader_memory; -mod pubdata; mod refund; #[cfg(test)] mod tests; mod transaction_data; mod utils; +mod version; mod vm; diff --git a/core/lib/multivm/src/versions/vm_fast/pubdata.rs b/core/lib/multivm/src/versions/vm_fast/pubdata.rs deleted file mode 100644 index f938696297b5..000000000000 --- a/core/lib/multivm/src/versions/vm_fast/pubdata.rs +++ /dev/null @@ -1,123 +0,0 @@ -use zksync_types::writes::{compress_state_diffs, StateDiffRecord}; - -use crate::interface::pubdata::L1MessengerL2ToL1Log; - -/// Struct based on which the pubdata blob is formed -#[derive(Debug, Clone, Default)] -pub(crate) struct PubdataInput { - pub(crate) user_logs: Vec, - pub(crate) l2_to_l1_messages: Vec>, - pub(crate) published_bytecodes: Vec>, - pub(crate) state_diffs: Vec, -} - -impl PubdataInput { - pub(crate) fn build_pubdata(self, with_uncompressed_state_diffs: bool) -> Vec { - let mut l1_messenger_pubdata = vec![]; - - let PubdataInput { - user_logs, - l2_to_l1_messages, - published_bytecodes, - state_diffs, - } = self; - - // Encoding user L2->L1 logs. - // Format: `[(numberOfL2ToL1Logs as u32) || l2tol1logs[1] || ... || l2tol1logs[n]]` - l1_messenger_pubdata.extend((user_logs.len() as u32).to_be_bytes()); - for l2tol1log in user_logs { - l1_messenger_pubdata.extend(l2tol1log.packed_encoding()); - } - - // Encoding L2->L1 messages - // Format: `[(numberOfMessages as u32) || (messages[1].len() as u32) || messages[1] || ... || (messages[n].len() as u32) || messages[n]]` - l1_messenger_pubdata.extend((l2_to_l1_messages.len() as u32).to_be_bytes()); - for message in l2_to_l1_messages { - l1_messenger_pubdata.extend((message.len() as u32).to_be_bytes()); - l1_messenger_pubdata.extend(message); - } - - // Encoding bytecodes - // Format: `[(numberOfBytecodes as u32) || (bytecodes[1].len() as u32) || bytecodes[1] || ... || (bytecodes[n].len() as u32) || bytecodes[n]]` - l1_messenger_pubdata.extend((published_bytecodes.len() as u32).to_be_bytes()); - for bytecode in published_bytecodes { - l1_messenger_pubdata.extend((bytecode.len() as u32).to_be_bytes()); - l1_messenger_pubdata.extend(bytecode); - } - - // Encoding state diffs - // Format: `[size of compressed state diffs u32 || compressed state diffs || (# state diffs: intial + repeated) as u32 || sorted state diffs by ]` - let state_diffs_compressed = compress_state_diffs(state_diffs.clone()); - l1_messenger_pubdata.extend(state_diffs_compressed); - - if with_uncompressed_state_diffs { - l1_messenger_pubdata.extend((state_diffs.len() as u32).to_be_bytes()); - for state_diff in state_diffs { - l1_messenger_pubdata.extend(state_diff.encode_padded()); - } - } - - l1_messenger_pubdata - } -} - -#[cfg(test)] -mod tests { - use zksync_system_constants::{ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS}; - use zksync_types::u256_to_h256; - - use super::*; - - #[test] - fn test_basic_pubdata_building() { - // Just using some constant addresses for tests - let addr1 = BOOTLOADER_ADDRESS; - let addr2 = ACCOUNT_CODE_STORAGE_ADDRESS; - - let user_logs = vec![L1MessengerL2ToL1Log { - l2_shard_id: 0, - is_service: false, - tx_number_in_block: 0, - sender: addr1, - key: 1.into(), - value: 128.into(), - }]; - - let l2_to_l1_messages = vec![hex::decode("deadbeef").unwrap()]; - - let published_bytecodes = vec![hex::decode("aaaabbbb").unwrap()]; - - // For covering more cases, we have two state diffs: - // One with enumeration index present (and so it is a repeated write) and the one without it. - let state_diffs = vec![ - StateDiffRecord { - address: addr2, - key: 155.into(), - derived_key: u256_to_h256(125.into()).0, - enumeration_index: 12, - initial_value: 11.into(), - final_value: 12.into(), - }, - StateDiffRecord { - address: addr2, - key: 156.into(), - derived_key: u256_to_h256(126.into()).0, - enumeration_index: 0, - initial_value: 0.into(), - final_value: 14.into(), - }, - ]; - - let input = PubdataInput { - user_logs, - l2_to_l1_messages, - published_bytecodes, - state_diffs, - }; - - let pubdata = - ethabi::encode(&[ethabi::Token::Bytes(input.build_pubdata(true))])[32..].to_vec(); - - assert_eq!(hex::encode(pubdata), "00000000000000000000000000000000000000000000000000000000000002c700000001000000000000000000000000000000000000000000008001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000100000004deadbeef0000000100000004aaaabbbb0100002a040001000000000000000000000000000000000000000000000000000000000000007e090e0000000c0901000000020000000000000000000000000000000000008002000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000000000007d000000000000000c000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008002000000000000000000000000000000000000000000000000000000000000009c000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); - } -} 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 e00a71a43c36..0a26e895b5a7 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/mod.rs @@ -112,7 +112,7 @@ impl TestedVm for Vm> { } fn finish_batch_without_pubdata(&mut self) -> VmExecutionResultAndLogs { - self.inspect_inner(&mut Default::default(), VmExecutionMode::Batch) + self.inspect_inner(&mut Default::default(), VmExecutionMode::Batch, None) } fn insert_bytecodes(&mut self, bytecodes: &[&[u8]]) { diff --git a/core/lib/multivm/src/versions/vm_fast/transaction_data.rs b/core/lib/multivm/src/versions/vm_fast/transaction_data.rs index afc0ef51e7d4..02697beee341 100644 --- a/core/lib/multivm/src/versions/vm_fast/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_fast/transaction_data.rs @@ -2,6 +2,7 @@ use std::convert::TryInto; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, h256_to_u256, @@ -11,7 +12,6 @@ use zksync_types::{ web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ utils::bytecode::bytes_to_be_words, @@ -195,7 +195,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } diff --git a/core/lib/multivm/src/versions/vm_fast/version.rs b/core/lib/multivm/src/versions/vm_fast/version.rs new file mode 100644 index 000000000000..8da180d8ba59 --- /dev/null +++ b/core/lib/multivm/src/versions/vm_fast/version.rs @@ -0,0 +1,28 @@ +use crate::{vm_latest::MultiVmSubversion, VmVersion}; + +#[derive(Debug, Copy, Clone)] +pub(crate) enum FastVmVersion { + IncreasedBootloaderMemory, + Gateway, +} + +impl From for MultiVmSubversion { + fn from(value: FastVmVersion) -> Self { + match value { + FastVmVersion::IncreasedBootloaderMemory => Self::IncreasedBootloaderMemory, + FastVmVersion::Gateway => Self::Gateway, + } + } +} + +impl TryFrom for FastVmVersion { + type Error = (); + + fn try_from(value: VmVersion) -> Result { + match value { + VmVersion::Vm1_5_0IncreasedBootloaderMemory => Ok(Self::IncreasedBootloaderMemory), + VmVersion::VmGateway => Ok(Self::Gateway), + _ => Err(()), + } + } +} diff --git a/core/lib/multivm/src/versions/vm_fast/vm.rs b/core/lib/multivm/src/versions/vm_fast/vm.rs index 2aab2bfc7d96..c935b1c0e7f5 100644 --- a/core/lib/multivm/src/versions/vm_fast/vm.rs +++ b/core/lib/multivm/src/versions/vm_fast/vm.rs @@ -5,6 +5,7 @@ use zk_evm_1_5_0::{ }; use zksync_contracts::SystemContractCode; use zksync_types::{ + bytecode::BytecodeHash, h256_to_u256, l1::is_l1_tx_type, l2_to_l1_log::UserL2ToL1Log, @@ -18,12 +19,10 @@ use zksync_types::{ Transaction, BOOTLOADER_ADDRESS, H160, H256, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, L2_BASE_TOKEN_ADDRESS, U256, }; -use zksync_utils::bytecode::hash_bytecode; use zksync_vm2::{ interface::{CallframeInterface, HeapId, StateInterface, Tracer}, ExecutionEnd, FatPointer, Program, Settings, StorageSlot, VirtualMachine, }; -use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use super::{ bootloader_state::{BootloaderState, BootloaderStateSnapshot}, @@ -37,32 +36,28 @@ use super::{ use crate::{ glue::GlueInto, interface::{ + pubdata::{PubdataBuilder, PubdataInput}, storage::{ImmutableStorageView, ReadStorage, StoragePtr, StorageView}, BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState, - ExecutionResult, FinishedL1Batch, Halt, L1BatchEnv, L2BlockEnv, PushTransactionResult, - Refunds, SystemEnv, TxRevertReason, VmEvent, VmExecutionLogs, VmExecutionMode, - VmExecutionResultAndLogs, VmExecutionStatistics, VmFactory, VmInterface, + ExecutionResult, FinishedL1Batch, Halt, InspectExecutionMode, L1BatchEnv, L2BlockEnv, + PushTransactionResult, Refunds, SystemEnv, TxRevertReason, VmEvent, VmExecutionLogs, + VmExecutionMode, VmExecutionResultAndLogs, VmExecutionStatistics, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmRevertReason, VmTrackingContracts, }, - is_supported_by_fast_vm, utils::events::extract_l2tol1logs_from_l1_messenger, vm_fast::{ bootloader_state::utils::{apply_l2_block, apply_pubdata_to_memory}, events::merge_events, - pubdata::PubdataInput, refund::compute_refund, + version::FastVmVersion, }, - vm_latest::{ - constants::{ - get_result_success_first_slot, get_vm_hook_params_start_position, get_vm_hook_position, - OPERATOR_REFUNDS_OFFSET, TX_GAS_LIMIT_OFFSET, VM_HOOK_PARAMS_COUNT, - }, - MultiVMSubversion, + vm_latest::constants::{ + get_result_success_first_slot, get_vm_hook_params_start_position, get_vm_hook_position, + OPERATOR_REFUNDS_OFFSET, TX_GAS_LIMIT_OFFSET, VM_HOOK_PARAMS_COUNT, }, + VmVersion, }; -const VM_VERSION: MultiVMSubversion = MultiVMSubversion::IncreasedBootloaderMemory; - type FullTracer = ((Tr, CircuitsTracer), EvmDeployTracer); #[derive(Debug)] @@ -103,17 +98,21 @@ pub struct Vm { pub(super) batch_env: L1BatchEnv, pub(super) system_env: SystemEnv, snapshot: Option, + vm_version: FastVmVersion, #[cfg(test)] enforced_state_diffs: Option>, } impl Vm { pub fn custom(batch_env: L1BatchEnv, system_env: SystemEnv, storage: S) -> Self { - assert!( - is_supported_by_fast_vm(system_env.version), - "Protocol version {:?} is not supported by fast VM", - system_env.version - ); + let vm_version: FastVmVersion = VmVersion::from(system_env.version) + .try_into() + .unwrap_or_else(|_| { + panic!( + "Protocol version {:?} is not supported by fast VM", + system_env.version + ) + }); let default_aa_code_hash = system_env.base_system_smart_contracts.default_aa.hash; let evm_emulator_hash = system_env @@ -147,7 +146,7 @@ impl Vm { Settings { default_aa_code_hash: default_aa_code_hash.into(), evm_interpreter_code_hash: evm_emulator_hash.into(), - hook_address: get_vm_hook_position(VM_VERSION) * 32, + hook_address: get_vm_hook_position(vm_version.into()) * 32, }, ); @@ -167,10 +166,12 @@ impl Vm { system_env.execution_mode, bootloader_memory.clone(), batch_env.first_l2_block, + system_env.version, ), system_env, batch_env, snapshot: None, + vm_version, #[cfg(test)] enforced_state_diffs: None, }; @@ -183,6 +184,7 @@ impl Vm { execution_mode: VmExecutionMode, tracer: &mut FullTracer, track_refunds: bool, + pubdata_builder: Option<&dyn PubdataBuilder>, ) -> VmRunResult { let mut refunds = Refunds { gas_refunded: 0, @@ -353,15 +355,19 @@ impl Vm { state_diffs: self.compute_state_diffs(), }; - // Save the pubdata for the future initial bootloader memory building - self.bootloader_state - .set_pubdata_input(pubdata_input.clone()); - // Apply the pubdata to the current memory let mut memory_to_apply = vec![]; - apply_pubdata_to_memory(&mut memory_to_apply, pubdata_input); + apply_pubdata_to_memory( + &mut memory_to_apply, + pubdata_builder.expect("`pubdata_builder` is required to finish batch"), + &pubdata_input, + self.system_env.version, + ); self.write_to_bootloader_heap(memory_to_apply); + + // Save the pubdata for the future initial bootloader memory building + self.bootloader_state.set_pubdata_input(pubdata_input); } Hook::PaymasterValidationEntered | Hook::ValidationStepEnded => { /* unused */ } @@ -386,8 +392,8 @@ impl Vm { } fn get_hook_params(&self) -> [U256; 3] { - (get_vm_hook_params_start_position(VM_VERSION) - ..get_vm_hook_params_start_position(VM_VERSION) + VM_HOOK_PARAMS_COUNT) + (get_vm_hook_params_start_position(self.vm_version.into()) + ..get_vm_hook_params_start_position(self.vm_version.into()) + VM_HOOK_PARAMS_COUNT) .map(|word| self.read_word_from_bootloader_heap(word as usize)) .collect::>() .try_into() @@ -396,7 +402,7 @@ impl Vm { fn get_tx_result(&self) -> U256 { let tx_idx = self.bootloader_state.current_tx(); - let slot = get_result_success_first_slot(VM_VERSION) as usize + tx_idx; + let slot = get_result_success_first_slot(self.vm_version.into()) as usize + tx_idx; self.read_word_from_bootloader_heap(slot) } @@ -457,7 +463,7 @@ impl Vm { pub(crate) fn insert_bytecodes<'a>(&mut self, bytecodes: impl IntoIterator) { for code in bytecodes { - let hash = h256_to_u256(hash_bytecode(code)); + let hash = BytecodeHash::for_bytecode(code).value_u256(); self.world.bytecode_cache.insert(hash, code.into()); } } @@ -578,6 +584,7 @@ impl Vm { &mut self, tracer: &mut Tr, execution_mode: VmExecutionMode, + pubdata_builder: Option<&dyn PubdataBuilder>, ) -> VmExecutionResultAndLogs { let mut track_refunds = false; if matches!(execution_mode, VmExecutionMode::OneTx) { @@ -593,7 +600,12 @@ impl Vm { (mem::take(tracer), CircuitsTracer::default()), EvmDeployTracer::new(self.world.dynamic_bytecodes.clone()), ); - let result = self.run(execution_mode, &mut full_tracer, track_refunds); + let result = self.run( + execution_mode, + &mut full_tracer, + track_refunds, + pubdata_builder, + ); let ((external_tracer, circuits_tracer), _) = full_tracer; *tracer = external_tracer; // place the tracer back @@ -712,7 +724,7 @@ impl VmInterface for Vm { tracer: &mut Self::TracerDispatcher, execution_mode: InspectExecutionMode, ) -> VmExecutionResultAndLogs { - self.inspect_inner(tracer, execution_mode.into()) + self.inspect_inner(tracer, execution_mode.into(), None) } fn inspect_transaction_with_bytecode_compression( @@ -739,19 +751,23 @@ impl VmInterface for Vm { self.bootloader_state.start_new_l2_block(l2_block_env) } - fn finish_batch(&mut self, _pubdata_builder: Rc) -> FinishedL1Batch { - let result = self.inspect_inner(&mut Tr::default(), VmExecutionMode::Batch); + fn finish_batch(&mut self, pubdata_builder: Rc) -> FinishedL1Batch { + let result = self.inspect_inner( + &mut Tr::default(), + VmExecutionMode::Batch, + Some(pubdata_builder.as_ref()), + ); let execution_state = self.get_current_execution_state(); - let bootloader_memory = self.bootloader_state.bootloader_memory(); + let bootloader_memory = self + .bootloader_state + .bootloader_memory(pubdata_builder.as_ref()); FinishedL1Batch { block_tip_execution_result: result, final_execution_state: execution_state, final_bootloader_memory: Some(bootloader_memory), pubdata_input: Some( self.bootloader_state - .get_pubdata_information() - .clone() - .build_pubdata(false), + .settlement_layer_pubdata(pubdata_builder.as_ref()), ), state_diffs: Some( self.bootloader_state diff --git a/core/lib/multivm/src/versions/vm_latest/constants.rs b/core/lib/multivm/src/versions/vm_latest/constants.rs index c047e6ffa3b0..c95771f9e849 100644 --- a/core/lib/multivm/src/versions/vm_latest/constants.rs +++ b/core/lib/multivm/src/versions/vm_latest/constants.rs @@ -5,7 +5,7 @@ pub use zk_evm_1_5_0::zkevm_opcode_defs::system_params::{ }; use zksync_system_constants::MAX_NEW_FACTORY_DEPS; -use super::vm::MultiVMSubversion; +use super::vm::MultiVmSubversion; use crate::vm_latest::old_vm::utils::heap_page_from_base; /// The amount of ergs to be reserved at the end of the batch to ensure that it has enough ergs to verify compression, etc. @@ -22,15 +22,15 @@ pub(crate) const MAX_BASE_LAYER_CIRCUITS: usize = 34100; /// the requirements on RAM. /// In this version of the VM the used bootloader memory bytes has increased from `30_000_000` to `59_000_000`, /// and then to `63_800_000` in a subsequent upgrade. -pub(crate) const fn get_used_bootloader_memory_bytes(subversion: MultiVMSubversion) -> usize { +pub(crate) const fn get_used_bootloader_memory_bytes(subversion: MultiVmSubversion) -> usize { match subversion { - MultiVMSubversion::SmallBootloaderMemory => 59_000_000, - MultiVMSubversion::IncreasedBootloaderMemory => 63_800_000, - MultiVMSubversion::Gateway => 63_800_000, + MultiVmSubversion::SmallBootloaderMemory => 59_000_000, + MultiVmSubversion::IncreasedBootloaderMemory => 63_800_000, + MultiVmSubversion::Gateway => 63_800_000, } } -pub(crate) const fn get_used_bootloader_memory_words(subversion: MultiVMSubversion) -> usize { +pub(crate) const fn get_used_bootloader_memory_words(subversion: MultiVmSubversion) -> usize { get_used_bootloader_memory_bytes(subversion) / 32 } @@ -105,7 +105,7 @@ pub(crate) const BOOTLOADER_TX_DESCRIPTION_OFFSET: usize = OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_OFFSET + OPERATOR_PROVIDED_L1_MESSENGER_PUBDATA_SLOTS; /// The size of the bootloader memory dedicated to the encodings of transactions -pub(crate) const fn get_bootloader_tx_encoding_space(subversion: MultiVMSubversion) -> u32 { +pub(crate) const fn get_bootloader_tx_encoding_space(subversion: MultiVmSubversion) -> u32 { (get_used_bootloader_memory_words(subversion) - TX_DESCRIPTION_OFFSET - MAX_TXS_IN_BATCH) as u32 } @@ -129,21 +129,21 @@ pub const BOOTLOADER_HEAP_PAGE: u32 = heap_page_from_base(MemoryPage(INITIAL_BAS /// So the layout looks like this: /// `[param 0][param 1][param 2][vmhook opcode]` pub const VM_HOOK_PARAMS_COUNT: u32 = 3; -pub(crate) const fn get_vm_hook_position(subversion: MultiVMSubversion) -> u32 { +pub(crate) const fn get_vm_hook_position(subversion: MultiVmSubversion) -> u32 { get_result_success_first_slot(subversion) - 1 } -pub(crate) const fn get_vm_hook_params_start_position(subversion: MultiVMSubversion) -> u32 { +pub(crate) const fn get_vm_hook_params_start_position(subversion: MultiVmSubversion) -> u32 { get_vm_hook_position(subversion) - VM_HOOK_PARAMS_COUNT } /// Method that provides the start position of the vm hook in the memory for the latest version of v1.5.0. /// This method is used only in `test_infra` in the bootloader tests and that's why it should be exposed. pub const fn get_vm_hook_start_position_latest() -> u32 { - get_vm_hook_params_start_position(MultiVMSubversion::IncreasedBootloaderMemory) + get_vm_hook_params_start_position(MultiVmSubversion::IncreasedBootloaderMemory) } /// Arbitrary space in memory closer to the end of the page -pub(crate) const fn get_result_success_first_slot(subversion: MultiVMSubversion) -> u32 { +pub(crate) const fn get_result_success_first_slot(subversion: MultiVmSubversion) -> u32 { ((get_used_bootloader_memory_bytes(subversion) as u32) - (MAX_TXS_IN_BATCH as u32) * 32) / 32 } diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs index d0390444e1cb..655f55bc8fc2 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs @@ -1,6 +1,5 @@ use itertools::Itertools; -use zksync_types::U256; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, U256}; use crate::{ interface::{ @@ -25,15 +24,14 @@ impl Vm { .storage .get_ptr() .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) + .is_bytecode_known(&BytecodeHash::for_bytecode(&info.original).value()) }) } } /// Converts bytecode to tokens and hashes it. pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { - let bytecode_hash = hash_bytecode(&bytecode); - let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value_u256(); let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } @@ -47,7 +45,11 @@ pub(crate) fn compress_bytecodes( .enumerate() .sorted_by_key(|(_idx, dep)| *dep) .dedup_by(|x, y| x.1 == y.1) - .filter(|(_idx, dep)| !storage.borrow_mut().is_bytecode_known(&hash_bytecode(dep))) + .filter(|(_idx, dep)| { + !storage + .borrow_mut() + .is_bytecode_known(&BytecodeHash::for_bytecode(dep).value()) + }) .sorted_by_key(|(idx, _dep)| *idx) .filter_map(|(_idx, dep)| bytecode::compress(dep.clone()).ok()) .collect() diff --git a/core/lib/multivm/src/versions/vm_latest/mod.rs b/core/lib/multivm/src/versions/vm_latest/mod.rs index 211c527c3816..46f8db789ddc 100644 --- a/core/lib/multivm/src/versions/vm_latest/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/mod.rs @@ -1,4 +1,4 @@ -pub(crate) use self::vm::MultiVMSubversion; +pub(crate) use self::vm::MultiVmSubversion; pub use self::{ bootloader_state::BootloaderState, old_vm::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tests/constants.rs b/core/lib/multivm/src/versions/vm_latest/tests/constants.rs index 3b75bfd6d36b..8ee62650ca77 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/constants.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/constants.rs @@ -3,7 +3,7 @@ #[test] fn test_that_bootloader_encoding_space_is_large_enoguh() { let encoding_space = crate::vm_latest::constants::get_bootloader_tx_encoding_space( - crate::vm_latest::MultiVMSubversion::latest(), + crate::vm_latest::MultiVmSubversion::latest(), ); assert!(encoding_space >= 330000, "Bootloader tx space is too small"); } 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 51c9dde0dd56..b059c9716d89 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs @@ -9,9 +9,9 @@ use zk_evm_1_5_0::{ zkevm_opcode_defs::{ContractCodeSha256Format, VersionedHashLen32}, }; use zksync_types::{ - h256_to_u256, writes::StateDiffRecord, StorageKey, StorageValue, Transaction, H256, U256, + bytecode::BytecodeHash, writes::StateDiffRecord, StorageKey, StorageValue, Transaction, H256, + U256, }; -use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::pubdata::PubdataBuilder; use super::{HistoryEnabled, Vm}; @@ -91,7 +91,7 @@ impl TestedVm for TestedLatestVm { self.batch_env.clone(), VmExecutionMode::Batch, diffs, - crate::vm_latest::MultiVMSubversion::latest(), + crate::vm_latest::MultiVmSubversion::latest(), Some(pubdata_builder), ); self.inspect_inner( @@ -113,9 +113,9 @@ impl TestedVm for TestedLatestVm { let bytecodes = bytecodes .iter() .map(|&bytecode| { - let hash = hash_bytecode(bytecode); + let hash = BytecodeHash::for_bytecode(bytecode).value_u256(); let words = bytes_to_be_words(bytecode); - (h256_to_u256(hash), words) + (hash, words) }) .collect(); self.state 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 7156acce152e..8755b98ddb8c 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 @@ -32,7 +32,7 @@ use crate::{ CircuitsTracer, RefundsTracer, ResultTracer, }, types::internals::ZkSyncVmState, - vm::MultiVMSubversion, + vm::MultiVmSubversion, VmTracer, }, }; @@ -65,7 +65,7 @@ pub struct DefaultExecutionTracer { pub(crate) circuits_tracer: CircuitsTracer, // This tracer is responsible for handling EVM deployments and providing the data to the code decommitter. pub(crate) evm_deploy_tracer: Option>, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, storage: StoragePtr, _phantom: PhantomData, } @@ -80,7 +80,7 @@ impl DefaultExecutionTracer { storage: StoragePtr, refund_tracer: Option>, pubdata_tracer: Option>, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, ) -> Self { Self { tx_has_been_processed: false, 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 98ae14ff7f89..2e6ab8089eb0 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 @@ -7,8 +7,9 @@ use zk_evm_1_5_0::{ FarCallOpcode, FatPointer, Opcode, CALL_IMPLICIT_CALLDATA_FAT_PTR_REGISTER, }, }; -use zksync_types::{h256_to_u256, CONTRACT_DEPLOYER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS}; -use zksync_utils::bytecode::hash_evm_bytecode; +use zksync_types::{ + bytecode::BytecodeHash, CONTRACT_DEPLOYER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, +}; use super::{traits::VmTracer, utils::read_pointer}; use crate::{ @@ -94,7 +95,7 @@ impl VmTracer for EvmDeployTracer { ) -> TracerExecutionStatus { let timestamp = Timestamp(state.local_state.timestamp); for published_bytecode in mem::take(&mut self.pending_bytecodes) { - let hash = h256_to_u256(hash_evm_bytecode(&published_bytecode)); + let hash = BytecodeHash::for_evm_bytecode(&published_bytecode).value_u256(); let as_words = bytes_to_be_words(&published_bytecode); state .decommittment_processor 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 4c71c3b2fc49..3698914630dd 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 @@ -33,7 +33,7 @@ use crate::{ tracers::{traits::VmTracer, utils::VmHook}, types::internals::ZkSyncVmState, utils::logs::collect_events_and_l1_system_logs_after_timestamp, - vm::MultiVMSubversion, + vm::MultiVmSubversion, StorageOracle, }, }; @@ -47,7 +47,7 @@ pub(crate) struct PubdataTracer { // For testing purposes it might be helpful to supply an exact set of state diffs to be provided // to the L1Messenger. enforced_state_diffs: Option>, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, pubdata_builder: Option>, _phantom_data: PhantomData, } @@ -56,7 +56,7 @@ impl PubdataTracer { pub(crate) fn new( l1_batch_env: L1BatchEnv, execution_mode: VmExecutionMode, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, pubdata_builder: Option>, ) -> Self { Self { @@ -77,7 +77,7 @@ impl PubdataTracer { l1_batch_env: L1BatchEnv, execution_mode: VmExecutionMode, forced_state_diffs: Vec, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, pubdata_builder: Option>, ) -> Self { Self { 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 f3fc1b167b45..6ef251c2db98 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs @@ -24,7 +24,7 @@ use crate::{ }, types::internals::ZkSyncVmState, utils::fee::get_batch_base_fee, - vm::MultiVMSubversion, + vm::MultiVmSubversion, }, }; @@ -50,12 +50,12 @@ pub(crate) struct RefundsTracer { spent_pubdata_counter_before: u32, l1_batch: L1BatchEnv, pubdata_published: u32, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, _phantom: PhantomData, } impl RefundsTracer { - pub(crate) fn new(l1_batch: L1BatchEnv, subversion: MultiVMSubversion) -> Self { + pub(crate) fn new(l1_batch: L1BatchEnv, subversion: MultiVmSubversion) -> Self { Self { pending_refund_request: None, refund_gas: 0, 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 0687c8393c62..80a3147f65d2 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 @@ -23,7 +23,7 @@ use crate::{ utils::{get_vm_hook_params, read_pointer, VmHook}, }, types::internals::ZkSyncVmState, - vm::MultiVMSubversion, + vm::MultiVmSubversion, BootloaderState, HistoryMode, SimpleMemory, }, }; @@ -102,7 +102,7 @@ pub(crate) struct ResultTracer { execution_mode: VmExecutionMode, far_call_tracker: FarCallTracker, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, pub(crate) tx_finished_in_one_tx_mode: bool, @@ -110,7 +110,7 @@ pub(crate) struct ResultTracer { } impl ResultTracer { - pub(crate) fn new(execution_mode: VmExecutionMode, subversion: MultiVMSubversion) -> Self { + pub(crate) fn new(execution_mode: VmExecutionMode, subversion: MultiVmSubversion) -> Self { Self { result: None, bootloader_out_of_gas: false, @@ -336,7 +336,7 @@ impl ResultTracer { pub(crate) fn tx_has_failed( state: &ZkSyncVmState, tx_id: u32, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, ) -> bool { let mem_slot = get_result_success_first_slot(subversion) + tx_id; let mem_value = state 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 50901dca62fc..6f81a3ac8de5 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs @@ -21,7 +21,7 @@ use crate::vm_latest::{ memory::SimpleMemory, utils::{aux_heap_page_from_base, heap_page_from_base}, }, - vm::MultiVMSubversion, + vm::MultiVmSubversion, }; #[derive(Clone, Debug, Copy)] @@ -47,7 +47,7 @@ impl VmHook { pub(crate) fn from_opcode_memory( state: &VmLocalStateData<'_>, data: &BeforeExecutionData, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, ) -> Self { let opcode_variant = data.opcode.variant; let heap_page = @@ -89,7 +89,7 @@ impl VmHook { pub(crate) fn get_debug_log( state: &VmLocalStateData<'_>, memory: &SimpleMemory, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, ) -> String { let vm_hook_params: Vec<_> = get_vm_hook_params(memory, subversion) .into_iter() @@ -161,7 +161,7 @@ pub(crate) fn print_debug_if_needed( state: &VmLocalStateData<'_>, memory: &SimpleMemory, latest_returndata_ptr: Option, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, ) { let log = match hook { VmHook::DebugLog => get_debug_log(state, memory, subversion), @@ -210,7 +210,7 @@ pub(crate) fn get_calldata_page_via_abi(far_call_abi: &FarCallABI, base_page: Me } pub(crate) fn get_vm_hook_params( memory: &SimpleMemory, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, ) -> Vec { let start_position = get_vm_hook_params_start_position(subversion); memory.dump_page_content_as_u256_words( diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs index 544934665adf..33f923414eb3 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs @@ -2,6 +2,7 @@ use std::convert::TryInto; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, h256_to_u256, @@ -11,7 +12,6 @@ use zksync_types::{ web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ utils::bytecode::bytes_to_be_words, @@ -208,7 +208,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } diff --git a/core/lib/multivm/src/versions/vm_latest/vm.rs b/core/lib/multivm/src/versions/vm_latest/vm.rs index 5a0e77023a5e..ada20af9fa3c 100644 --- a/core/lib/multivm/src/versions/vm_latest/vm.rs +++ b/core/lib/multivm/src/versions/vm_latest/vm.rs @@ -35,7 +35,7 @@ use crate::{ /// version was released with increased bootloader memory. The version with the small bootloader memory /// is available only on internal staging environments. #[derive(Debug, Copy, Clone)] -pub(crate) enum MultiVMSubversion { +pub(crate) enum MultiVmSubversion { /// The initial version of v1.5.0, available only on staging environments. SmallBootloaderMemory, /// The final correct version of v1.5.0 @@ -44,7 +44,7 @@ pub(crate) enum MultiVMSubversion { Gateway, } -impl MultiVMSubversion { +impl MultiVmSubversion { #[cfg(test)] pub(crate) fn latest() -> Self { Self::IncreasedBootloaderMemory @@ -53,7 +53,7 @@ impl MultiVMSubversion { #[derive(Debug)] pub(crate) struct VmVersionIsNotVm150Error; -impl TryFrom for MultiVMSubversion { +impl TryFrom for MultiVmSubversion { type Error = VmVersionIsNotVm150Error; fn try_from(value: VmVersion) -> Result { match value { @@ -77,7 +77,7 @@ pub struct Vm { pub(crate) batch_env: L1BatchEnv, // Snapshots for the current run pub(crate) snapshots: Vec, - pub(crate) subversion: MultiVMSubversion, + pub(crate) subversion: MultiVmSubversion, _phantom: std::marker::PhantomData, } @@ -247,7 +247,7 @@ impl Vm { batch_env: L1BatchEnv, system_env: SystemEnv, storage: StoragePtr, - subversion: MultiVMSubversion, + subversion: MultiVmSubversion, ) -> Self { let (state, bootloader_state) = new_vm_state(storage.clone(), &system_env, &batch_env); Self { diff --git a/core/lib/multivm/src/versions/vm_m5/oracle_tools.rs b/core/lib/multivm/src/versions/vm_m5/oracle_tools.rs index 32930f31cd71..f430ad346387 100644 --- a/core/lib/multivm/src/versions/vm_m5/oracle_tools.rs +++ b/core/lib/multivm/src/versions/vm_m5/oracle_tools.rs @@ -10,7 +10,7 @@ use crate::vm_m5::{ storage::StorageOracle, }, storage::{Storage, StoragePtr}, - vm_instance::MultiVMSubversion, + vm_instance::MultiVmSubversion, }; #[derive(Debug)] @@ -25,7 +25,7 @@ pub struct OracleTools { } impl OracleTools { - pub fn new(storage_pointer: StoragePtr, refund_state: MultiVMSubversion) -> Self { + pub fn new(storage_pointer: StoragePtr, refund_state: MultiVmSubversion) -> Self { Self { storage: StorageOracle::new(storage_pointer.clone(), refund_state), memory: SimpleMemory::default(), diff --git a/core/lib/multivm/src/versions/vm_m5/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_m5/oracles/decommitter.rs index ca6fde506f87..7e2264201e11 100644 --- a/core/lib/multivm/src/versions/vm_m5/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_m5/oracles/decommitter.rs @@ -7,11 +7,10 @@ use zk_evm_1_3_1::{ }, }; use zksync_types::{u256_to_h256, U256}; -use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ - utils::bytecode::bytes_to_be_words, + utils::bytecode::{bytecode_len_in_words, bytes_to_be_words}, vm_m5::{ history_recorder::HistoryRecorder, storage::{Storage, StoragePtr}, diff --git a/core/lib/multivm/src/versions/vm_m5/oracles/storage.rs b/core/lib/multivm/src/versions/vm_m5/oracles/storage.rs index ab373e9e7696..90bd9cfaab69 100644 --- a/core/lib/multivm/src/versions/vm_m5/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_m5/oracles/storage.rs @@ -18,7 +18,7 @@ use crate::vm_m5::{ }, storage::{Storage, StoragePtr}, utils::StorageLogQuery, - vm_instance::MultiVMSubversion, + vm_instance::MultiVmSubversion, }; // While the storage does not support different shards, it was decided to write the @@ -45,7 +45,7 @@ pub struct StorageOracle { // to cover this slot. pub paid_changes: HistoryRecorder>, - pub refund_state: MultiVMSubversion, + pub refund_state: MultiVmSubversion, } impl OracleWithHistory for StorageOracle { @@ -63,7 +63,7 @@ impl OracleWithHistory for StorageOracle { } impl StorageOracle { - pub fn new(storage: StoragePtr, refund_state: MultiVMSubversion) -> Self { + pub fn new(storage: StoragePtr, refund_state: MultiVmSubversion) -> Self { Self { storage: HistoryRecorder::from_inner(StorageWrapper::new(storage)), frames_stack: Default::default(), @@ -74,10 +74,10 @@ impl StorageOracle { fn is_storage_key_free(&self, key: &StorageKey) -> bool { match self.refund_state { - MultiVMSubversion::V1 => { + MultiVmSubversion::V1 => { key.address() == &zksync_system_constants::SYSTEM_CONTEXT_ADDRESS } - MultiVMSubversion::V2 => { + MultiVmSubversion::V2 => { key.address() == &zksync_system_constants::SYSTEM_CONTEXT_ADDRESS || *key == storage_key_for_eth_balance(&BOOTLOADER_ADDRESS) } diff --git a/core/lib/multivm/src/versions/vm_m5/pubdata_utils.rs b/core/lib/multivm/src/versions/vm_m5/pubdata_utils.rs index 1fd8c2460930..8eca2ef5cd86 100644 --- a/core/lib/multivm/src/versions/vm_m5/pubdata_utils.rs +++ b/core/lib/multivm/src/versions/vm_m5/pubdata_utils.rs @@ -4,11 +4,11 @@ use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_querie use itertools::Itertools; use zk_evm_1_3_1::aux_structures::{LogQuery, Timestamp}; use zksync_types::{StorageKey, PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; -use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ glue::GlueInto, interface::VmEvent, + utils::bytecode::bytecode_len_in_bytes, vm_m5::{ oracles::storage::storage_key_of_log, storage::Storage, utils::collect_storage_log_queries_after_timestamp, vm_instance::VmInstance, @@ -35,9 +35,7 @@ impl VmInstance { let published_bytecode_bytes: u32 = VmEvent::extract_published_bytecodes(&events) .iter() - .map(|bytecodehash| { - bytecode_len_in_bytes(*bytecodehash) as u32 + PUBLISH_BYTECODE_OVERHEAD - }) + .map(|bytecode_hash| bytecode_len_in_bytes(bytecode_hash) + PUBLISH_BYTECODE_OVERHEAD) .sum(); storage_writes_pubdata_published diff --git a/core/lib/multivm/src/versions/vm_m5/test_utils.rs b/core/lib/multivm/src/versions/vm_m5/test_utils.rs index ff6ed0392c85..e0e377e85971 100644 --- a/core/lib/multivm/src/versions/vm_m5/test_utils.rs +++ b/core/lib/multivm/src/versions/vm_m5/test_utils.rs @@ -15,12 +15,12 @@ use zk_evm_1_3_1::{ use zksync_contracts::deployer_contract; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{Address, Token}, h256_to_address, u256_to_h256, web3::keccak256, Execute, Nonce, StorageKey, StorageValue, CONTRACT_DEPLOYER_ADDRESS, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use super::utils::StorageLogQuery; use crate::vm_m5::{ @@ -143,7 +143,7 @@ pub fn get_create_execute(code: &[u8], calldata: &[u8]) -> Execute { let params = [ Token::FixedBytes(vec![0u8; 32]), - Token::FixedBytes(hash_bytecode(code).0.to_vec()), + Token::FixedBytes(BytecodeHash::for_bytecode(code).value().0.to_vec()), Token::Bytes(calldata.to_vec()), ]; let calldata = contract_function diff --git a/core/lib/multivm/src/versions/vm_m5/transaction_data.rs b/core/lib/multivm/src/versions/vm_m5/transaction_data.rs index 2307c5e24127..236c4c3d4122 100644 --- a/core/lib/multivm/src/versions/vm_m5/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_m5/transaction_data.rs @@ -1,13 +1,14 @@ use zk_evm_1_3_1::zkevm_opcode_defs::system_params::{MAX_PUBDATA_PER_BLOCK, MAX_TX_ERGS_LIMIT}; use zksync_types::{ - address_to_h256, ceil_div_u256, + address_to_h256, + bytecode::BytecodeHash, + ceil_div_u256, ethabi::{encode, Address, Token}, fee::encoding_len, h256_to_u256, l2::TransactionType, ExecuteTransactionCommon, Transaction, U256, }; -use zksync_utils::bytecode::hash_bytecode; use super::vm_with_bootloader::MAX_GAS_PER_PUBDATA_BYTE; use crate::{ @@ -168,7 +169,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } diff --git a/core/lib/multivm/src/versions/vm_m5/vm.rs b/core/lib/multivm/src/versions/vm_m5/vm.rs index 266a0a437e5e..bd104b868401 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm.rs @@ -12,7 +12,7 @@ use crate::{ }, vm_m5::{ storage::Storage, - vm_instance::{MultiVMSubversion, VmInstance}, + vm_instance::{MultiVmSubversion, VmInstance}, }, }; @@ -28,7 +28,7 @@ impl Vm { batch_env: L1BatchEnv, system_env: SystemEnv, storage: StoragePtr, - vm_sub_version: MultiVMSubversion, + vm_sub_version: MultiVmSubversion, ) -> Self { let oracle_tools = crate::vm_m5::OracleTools::new(storage.clone(), vm_sub_version); let block_properties = zk_evm_1_3_1::block_properties::BlockProperties { @@ -127,8 +127,8 @@ impl VmFactory for Vm { fn new(batch_env: L1BatchEnv, system_env: SystemEnv, storage: StoragePtr) -> Self { let vm_version: VmVersion = system_env.version.into(); let vm_sub_version = match vm_version { - VmVersion::M5WithoutRefunds => MultiVMSubversion::V1, - VmVersion::M5WithRefunds => MultiVMSubversion::V2, + VmVersion::M5WithoutRefunds => MultiVmSubversion::V1, + VmVersion::M5WithRefunds => MultiVmSubversion::V2, _ => panic!("Unsupported protocol version for vm_m5: {:?}", vm_version), }; Self::new_with_subversion(batch_env, system_env, storage, vm_sub_version) diff --git a/core/lib/multivm/src/versions/vm_m5/vm_instance.rs b/core/lib/multivm/src/versions/vm_m5/vm_instance.rs index 4a96c4a750cc..94b86bce7ea7 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm_instance.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm_instance.rs @@ -81,7 +81,7 @@ pub(crate) fn get_vm_hook_params(memory: &SimpleMemory) -> Vec { /// /// This enum allows to execute blocks with the same VM but different support for refunds. #[derive(Debug, Copy, Clone)] -pub enum MultiVMSubversion { +pub enum MultiVmSubversion { /// Initial VM M5 version, refunds are fully disabled. V1, /// Refunds were enabled. ETH balance for bootloader address was marked as a free slot. @@ -99,7 +99,7 @@ pub struct VmInstance { pub snapshots: Vec, /// MultiVM-specific addition. See enum doc-comment for details. - pub(crate) refund_state: MultiVMSubversion, + pub(crate) refund_state: MultiVmSubversion, } /// This structure stores data that accumulates during the VM run. @@ -560,12 +560,12 @@ impl VmInstance { let refund_to_propose; let refund_slot; match self.refund_state { - MultiVMSubversion::V1 => { + MultiVmSubversion::V1 => { refund_to_propose = bootloader_refund; refund_slot = OPERATOR_REFUNDS_OFFSET + self.bootloader_state.tx_to_execute() - 1; } - MultiVMSubversion::V2 => { + MultiVmSubversion::V2 => { let gas_spent_on_pubdata = tracer .gas_spent_on_pubdata(&self.state.local_state) - spent_pubdata_counter_before; diff --git a/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs b/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs index 653169cd7ff0..0a7df48df80f 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs @@ -14,10 +14,9 @@ use zk_evm_1_3_1::{ use zksync_contracts::BaseSystemContracts; use zksync_system_constants::MAX_L2_TX_GAS_LIMIT; use zksync_types::{ - address_to_u256, fee_model::L1PeggedBatchFeeModelInput, h256_to_u256, Address, Transaction, - BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, + address_to_u256, bytecode::BytecodeHash, fee_model::L1PeggedBatchFeeModelInput, h256_to_u256, + Address, Transaction, BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::L1BatchEnv, @@ -30,7 +29,7 @@ use crate::{ utils::{ code_page_candidate_from_base, heap_page_from_base, BLOCK_GAS_LIMIT, INITIAL_BASE_PAGE, }, - vm_instance::{MultiVMSubversion, VmInstance, ZkSyncVmState}, + vm_instance::{MultiVmSubversion, VmInstance, ZkSyncVmState}, OracleTools, }, }; @@ -222,7 +221,7 @@ impl Default for TxExecutionMode { } pub fn init_vm( - refund_state: MultiVMSubversion, + refund_state: MultiVmSubversion, oracle_tools: OracleTools, block_context: BlockContextMode, block_properties: BlockProperties, @@ -241,7 +240,7 @@ pub fn init_vm( } pub fn init_vm_with_gas_limit( - refund_state: MultiVMSubversion, + refund_state: MultiVmSubversion, oracle_tools: OracleTools, block_context: BlockContextMode, block_properties: BlockProperties, @@ -338,7 +337,7 @@ impl BlockContextMode { // This method accepts a custom bootloader code. // It should be used only in tests. pub fn init_vm_inner( - refund_state: MultiVMSubversion, + refund_state: MultiVmSubversion, mut oracle_tools: OracleTools, block_context: BlockContextMode, block_properties: BlockProperties, @@ -585,8 +584,7 @@ fn formal_calldata_abi() -> PrimitiveValue { } pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { - let bytecode_hash = hash_bytecode(&bytecode); - let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value_u256(); let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_m6/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_m6/oracles/decommitter.rs index a43ec4ec4fd8..5bd33d6d49c1 100644 --- a/core/lib/multivm/src/versions/vm_m6/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_m6/oracles/decommitter.rs @@ -7,11 +7,10 @@ use zk_evm_1_3_1::{ }, }; use zksync_types::{u256_to_h256, U256}; -use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ - utils::bytecode::bytes_to_be_words, + utils::bytecode::{bytecode_len_in_words, bytes_to_be_words}, vm_m6::{ history_recorder::{HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory}, storage::{Storage, StoragePtr}, diff --git a/core/lib/multivm/src/versions/vm_m6/pubdata_utils.rs b/core/lib/multivm/src/versions/vm_m6/pubdata_utils.rs index 196883e1c936..97bf290a2162 100644 --- a/core/lib/multivm/src/versions/vm_m6/pubdata_utils.rs +++ b/core/lib/multivm/src/versions/vm_m6/pubdata_utils.rs @@ -4,11 +4,11 @@ use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_querie use itertools::Itertools; use zk_evm_1_3_1::aux_structures::{LogQuery, Timestamp}; use zksync_types::{StorageKey, PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; -use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ glue::GlueInto, interface::VmEvent, + utils::bytecode::bytecode_len_in_bytes, vm_m6::{ history_recorder::HistoryMode, oracles::storage::storage_key_of_log, storage::Storage, utils::collect_storage_log_queries_after_timestamp, VmInstance, @@ -35,9 +35,7 @@ impl VmInstance { let published_bytecode_bytes: u32 = VmEvent::extract_published_bytecodes(&events) .iter() - .map(|bytecodehash| { - bytecode_len_in_bytes(*bytecodehash) as u32 + PUBLISH_BYTECODE_OVERHEAD - }) + .map(|bytecode_hash| bytecode_len_in_bytes(bytecode_hash) + PUBLISH_BYTECODE_OVERHEAD) .sum(); storage_writes_pubdata_published diff --git a/core/lib/multivm/src/versions/vm_m6/test_utils.rs b/core/lib/multivm/src/versions/vm_m6/test_utils.rs index 438a67129ac6..0debd8dea568 100644 --- a/core/lib/multivm/src/versions/vm_m6/test_utils.rs +++ b/core/lib/multivm/src/versions/vm_m6/test_utils.rs @@ -13,12 +13,12 @@ use zk_evm_1_3_1::{aux_structures::Timestamp, vm_state::VmLocalState}; use zksync_contracts::deployer_contract; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{Address, Token}, h256_to_address, u256_to_h256, web3::keccak256, Execute, Nonce, StorageKey, StorageValue, CONTRACT_DEPLOYER_ADDRESS, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use super::utils::StorageLogQuery; use crate::vm_m6::{ @@ -143,7 +143,7 @@ pub fn get_create_execute(code: &[u8], calldata: &[u8]) -> Execute { let params = [ Token::FixedBytes(vec![0u8; 32]), - Token::FixedBytes(hash_bytecode(code).0.to_vec()), + Token::FixedBytes(BytecodeHash::for_bytecode(code).value().0.to_vec()), Token::Bytes(calldata.to_vec()), ]; let calldata = contract_function diff --git a/core/lib/multivm/src/versions/vm_m6/transaction_data.rs b/core/lib/multivm/src/versions/vm_m6/transaction_data.rs index cfd2ebf00e44..d0835b233009 100644 --- a/core/lib/multivm/src/versions/vm_m6/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_m6/transaction_data.rs @@ -1,6 +1,8 @@ use zk_evm_1_3_1::zkevm_opcode_defs::system_params::MAX_TX_ERGS_LIMIT; use zksync_types::{ - address_to_h256, ceil_div_u256, + address_to_h256, + bytecode::BytecodeHash, + ceil_div_u256, ethabi::{encode, Address, Token}, fee::encoding_len, h256_to_u256, @@ -8,7 +10,6 @@ use zksync_types::{ l2::TransactionType, ExecuteTransactionCommon, Transaction, MAX_L2_TX_GAS_LIMIT, U256, }; -use zksync_utils::bytecode::hash_bytecode; use super::vm_with_bootloader::{MAX_GAS_PER_PUBDATA_BYTE, MAX_TXS_IN_BLOCK}; use crate::{ @@ -195,7 +196,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } diff --git a/core/lib/multivm/src/versions/vm_m6/vm.rs b/core/lib/multivm/src/versions/vm_m6/vm.rs index 0443dc8fb55e..ff089ba902dd 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm.rs @@ -1,7 +1,6 @@ use std::{collections::HashSet, rc::Rc}; -use zksync_types::{h256_to_u256, vm::VmVersion, Transaction}; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, h256_to_u256, vm::VmVersion, Transaction}; use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ @@ -14,7 +13,7 @@ use crate::{ }, tracers::old::TracerDispatcher, utils::bytecode, - vm_m6::{storage::Storage, vm_instance::MultiVMSubversion, VmInstance}, + vm_m6::{storage::Storage, vm_instance::MultiVmSubversion, VmInstance}, }; #[derive(Debug)] @@ -28,7 +27,7 @@ impl Vm { batch_env: L1BatchEnv, system_env: SystemEnv, storage: StoragePtr, - vm_sub_version: MultiVMSubversion, + vm_sub_version: MultiVmSubversion, ) -> Self { let oracle_tools = crate::vm_m6::OracleTools::new(storage.clone(), H::VmM6Mode::default()); let block_properties = zk_evm_1_3_1::block_properties::BlockProperties { @@ -143,7 +142,7 @@ impl VmInterface for Vm { let mut deps_hashes = HashSet::with_capacity(deps.len()); let mut bytecode_hashes = vec![]; let filtered_deps = deps.iter().filter_map(|bytecode| { - let bytecode_hash = hash_bytecode(bytecode); + let bytecode_hash = BytecodeHash::for_bytecode(bytecode).value(); let is_known = !deps_hashes.insert(bytecode_hash) || self.vm.is_bytecode_exists(&bytecode_hash); @@ -220,8 +219,8 @@ impl VmFactory for Vm { fn new(batch_env: L1BatchEnv, system_env: SystemEnv, storage: StoragePtr) -> Self { let vm_version: VmVersion = system_env.version.into(); let vm_sub_version = match vm_version { - VmVersion::M6Initial => MultiVMSubversion::V1, - VmVersion::M6BugWithCompressionFixed => MultiVMSubversion::V2, + VmVersion::M6Initial => MultiVmSubversion::V1, + VmVersion::M6BugWithCompressionFixed => MultiVmSubversion::V2, _ => panic!("Unsupported protocol version for vm_m6: {:?}", vm_version), }; Self::new_with_subversion(batch_env, system_env, storage, vm_sub_version) diff --git a/core/lib/multivm/src/versions/vm_m6/vm_instance.rs b/core/lib/multivm/src/versions/vm_m6/vm_instance.rs index d6c418da4c20..29ef17aa4bc7 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm_instance.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm_instance.rs @@ -82,7 +82,7 @@ pub(crate) fn get_vm_hook_params(memory: &SimpleMemory) -> Ve /// /// This enum allows to execute blocks with the same VM but different support for refunds. #[derive(Debug, Copy, Clone)] -pub enum MultiVMSubversion { +pub enum MultiVmSubversion { /// Initial VM M6 version. V1, /// Bug with code compression was fixed. @@ -98,7 +98,7 @@ pub struct VmInstance { pub(crate) bootloader_state: BootloaderState, pub snapshots: Vec, - pub vm_subversion: MultiVMSubversion, + pub vm_subversion: MultiVmSubversion, } /// This structure stores data that accumulates during the VM run. diff --git a/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs b/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs index a47ffb116364..ff83abc45fcf 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs @@ -14,10 +14,9 @@ use zk_evm_1_3_1::{ use zksync_contracts::BaseSystemContracts; use zksync_system_constants::MAX_L2_TX_GAS_LIMIT; use zksync_types::{ - address_to_u256, fee_model::L1PeggedBatchFeeModelInput, h256_to_u256, Address, Transaction, - BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, + address_to_u256, bytecode::BytecodeHash, fee_model::L1PeggedBatchFeeModelInput, h256_to_u256, + Address, Transaction, BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{CompressedBytecodeInfo, L1BatchEnv}, @@ -30,7 +29,7 @@ use crate::{ utils::{ code_page_candidate_from_base, heap_page_from_base, BLOCK_GAS_LIMIT, INITIAL_BASE_PAGE, }, - vm_instance::{MultiVMSubversion, ZkSyncVmState}, + vm_instance::{MultiVmSubversion, ZkSyncVmState}, OracleTools, VmInstance, }, }; @@ -270,7 +269,7 @@ impl Default for TxExecutionMode { } pub fn init_vm( - vm_subversion: MultiVMSubversion, + vm_subversion: MultiVmSubversion, oracle_tools: OracleTools, block_context: BlockContextMode, block_properties: BlockProperties, @@ -289,7 +288,7 @@ pub fn init_vm( } pub fn init_vm_with_gas_limit( - vm_subversion: MultiVMSubversion, + vm_subversion: MultiVmSubversion, oracle_tools: OracleTools, block_context: BlockContextMode, block_properties: BlockProperties, @@ -386,7 +385,7 @@ impl BlockContextMode { // This method accepts a custom bootloader code. // It should be used only in tests. pub fn init_vm_inner( - vm_subversion: MultiVMSubversion, + vm_subversion: MultiVmSubversion, mut oracle_tools: OracleTools, block_context: BlockContextMode, block_properties: BlockProperties, @@ -434,7 +433,7 @@ fn bootloader_initial_memory(block_properties: &BlockContextMode) -> Vec<(usize, } pub fn get_bootloader_memory( - vm_subversion: MultiVMSubversion, + vm_subversion: MultiVmSubversion, txs: Vec, predefined_refunds: Vec, predefined_compressed_bytecodes: Vec>, @@ -442,14 +441,14 @@ pub fn get_bootloader_memory( block_context: BlockContextMode, ) -> Vec<(usize, U256)> { match vm_subversion { - MultiVMSubversion::V1 => get_bootloader_memory_v1( + MultiVmSubversion::V1 => get_bootloader_memory_v1( txs, predefined_refunds, predefined_compressed_bytecodes, execution_mode, block_context, ), - MultiVMSubversion::V2 => get_bootloader_memory_v2( + MultiVmSubversion::V2 => get_bootloader_memory_v2( txs, predefined_refunds, predefined_compressed_bytecodes, @@ -576,14 +575,14 @@ pub fn push_raw_transaction_to_bootloader_memory( explicit_compressed_bytecodes: Option>, ) -> Vec { match vm.vm_subversion { - MultiVMSubversion::V1 => push_raw_transaction_to_bootloader_memory_v1( + MultiVmSubversion::V1 => push_raw_transaction_to_bootloader_memory_v1( vm, tx, execution_mode, predefined_overhead, explicit_compressed_bytecodes, ), - MultiVMSubversion::V2 => push_raw_transaction_to_bootloader_memory_v2( + MultiVmSubversion::V2 => push_raw_transaction_to_bootloader_memory_v2( vm, tx, execution_mode, @@ -620,7 +619,7 @@ fn push_raw_transaction_to_bootloader_memory_v1( tx.factory_deps .iter() .filter_map(|bytecode| { - if vm.is_bytecode_exists(&hash_bytecode(bytecode)) { + if vm.is_bytecode_exists(&BytecodeHash::for_bytecode(bytecode).value()) { return None; } bytecode::compress(bytecode.clone()).ok() @@ -692,7 +691,7 @@ fn push_raw_transaction_to_bootloader_memory_v2( tx.factory_deps .iter() .filter_map(|bytecode| { - if vm.is_bytecode_exists(&hash_bytecode(bytecode)) { + if vm.is_bytecode_exists(&BytecodeHash::for_bytecode(bytecode).value()) { return None; } bytecode::compress(bytecode.clone()).ok() @@ -905,8 +904,7 @@ fn formal_calldata_abi() -> PrimitiveValue { } pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { - let bytecode_hash = hash_bytecode(&bytecode); - let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value_u256(); let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs index 766cac391e32..38cfaa124b16 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs @@ -1,6 +1,5 @@ use itertools::Itertools; -use zksync_types::U256; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, U256}; use crate::{ interface::{ @@ -25,15 +24,14 @@ impl Vm { .storage .get_ptr() .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) + .is_bytecode_known(&BytecodeHash::for_bytecode(&info.original).value()) }) } } /// Converts bytecode to tokens and hashes it. pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { - let bytecode_hash = hash_bytecode(&bytecode); - let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value_u256(); let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } @@ -47,7 +45,11 @@ pub(crate) fn compress_bytecodes( .enumerate() .sorted_by_key(|(_idx, dep)| *dep) .dedup_by(|x, y| x.1 == y.1) - .filter(|(_idx, dep)| !storage.borrow_mut().is_bytecode_known(&hash_bytecode(dep))) + .filter(|(_idx, dep)| { + !storage + .borrow_mut() + .is_bytecode_known(&BytecodeHash::for_bytecode(dep).value()) + }) .sorted_by_key(|(idx, _dep)| *idx) .filter_map(|(_idx, dep)| bytecode::compress(dep.clone()).ok()) .collect() diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/oracles/decommitter.rs index fc9d0794b958..b0ce7edbc95d 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/oracles/decommitter.rs @@ -7,12 +7,11 @@ use zk_evm_1_3_3::{ }, }; use zksync_types::{u256_to_h256, U256}; -use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, - utils::bytecode::bytes_to_be_words, + utils::bytecode::{bytecode_len_in_words, bytes_to_be_words}, vm_refunds_enhancement::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs index 98fee074a940..777f0d51460f 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs @@ -6,7 +6,6 @@ use zk_evm_1_3_3::{ }; use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; use zksync_types::{ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, U256}; -use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ @@ -15,6 +14,7 @@ use crate::{ L1BatchEnv, Refunds, VmEvent, }, tracers::dynamic::vm_1_3_3::DynTracer, + utils::bytecode::bytecode_len_in_bytes, vm_refunds_enhancement::{ bootloader_state::BootloaderState, constants::{BOOTLOADER_HEAP_PAGE, OPERATOR_REFUNDS_OFFSET, TX_GAS_LIMIT_OFFSET}, @@ -335,7 +335,7 @@ pub(crate) fn pubdata_published( let published_bytecode_bytes: u32 = VmEvent::extract_published_bytecodes(&events) .iter() - .map(|bytecodehash| bytecode_len_in_bytes(*bytecodehash) as u32 + PUBLISH_BYTECODE_OVERHEAD) + .map(|bytecode_hash| bytecode_len_in_bytes(bytecode_hash) + PUBLISH_BYTECODE_OVERHEAD) .sum(); storage_writes_pubdata_published diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/transaction_data.rs index 5bc13bfac2d0..64802d74c878 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/transaction_data.rs @@ -2,6 +2,7 @@ use std::convert::TryInto; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, h256_to_u256, @@ -11,7 +12,6 @@ use zksync_types::{ web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ utils::bytecode::bytes_to_be_words, @@ -195,7 +195,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs index 2b26d4fc9d6d..828b1c961708 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs @@ -1,6 +1,5 @@ use itertools::Itertools; -use zksync_types::U256; -use zksync_utils::bytecode::hash_bytecode; +use zksync_types::{bytecode::BytecodeHash, U256}; use crate::{ interface::{ @@ -25,15 +24,14 @@ impl Vm { .storage .get_ptr() .borrow_mut() - .is_bytecode_known(&hash_bytecode(&info.original)) + .is_bytecode_known(&BytecodeHash::for_bytecode(&info.original).value()) }) } } /// Converts bytecode to tokens and hashes it. pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { - let bytecode_hash = hash_bytecode(&bytecode); - let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); + let bytecode_hash = BytecodeHash::for_bytecode(&bytecode).value_u256(); let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } @@ -47,7 +45,11 @@ pub(crate) fn compress_bytecodes( .enumerate() .sorted_by_key(|(_idx, dep)| *dep) .dedup_by(|x, y| x.1 == y.1) - .filter(|(_idx, dep)| !storage.borrow_mut().is_bytecode_known(&hash_bytecode(dep))) + .filter(|(_idx, dep)| { + !storage + .borrow_mut() + .is_bytecode_known(&BytecodeHash::for_bytecode(dep).value()) + }) .sorted_by_key(|(idx, _dep)| *idx) .filter_map(|(_idx, dep)| bytecode::compress(dep.clone()).ok()) .collect() diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/decommitter.rs index fad51513dbca..a432e782f658 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/decommitter.rs @@ -7,12 +7,11 @@ use zk_evm_1_3_3::{ }, }; use zksync_types::{u256_to_h256, U256}; -use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, - utils::bytecode::bytes_to_be_words, + utils::bytecode::{bytecode_len_in_words, bytes_to_be_words}, vm_virtual_blocks::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs index b35dfecfa400..59aa837cd8fb 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs @@ -11,7 +11,6 @@ use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS} use zksync_types::{ ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, StorageKey, U256, }; -use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ @@ -19,6 +18,7 @@ use crate::{ L1BatchEnv, Refunds, VmEvent, VmExecutionResultAndLogs, }, tracers::dynamic::vm_1_3_3::DynTracer, + utils::bytecode::bytecode_len_in_bytes, vm_virtual_blocks::{ bootloader_state::BootloaderState, constants::{BOOTLOADER_HEAP_PAGE, OPERATOR_REFUNDS_OFFSET, TX_GAS_LIMIT_OFFSET}, @@ -329,7 +329,7 @@ pub(crate) fn pubdata_published( let published_bytecode_bytes: u32 = VmEvent::extract_published_bytecodes(&events) .iter() - .map(|bytecodehash| bytecode_len_in_bytes(*bytecodehash) as u32 + PUBLISH_BYTECODE_OVERHEAD) + .map(|bytecode_hash| bytecode_len_in_bytes(bytecode_hash) + PUBLISH_BYTECODE_OVERHEAD) .sum(); storage_writes_pubdata_published diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/transaction_data.rs index a2540d12a670..d13304c93285 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/transaction_data.rs @@ -2,6 +2,7 @@ use std::convert::TryInto; use zksync_types::{ address_to_h256, + bytecode::BytecodeHash, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, h256_to_u256, @@ -11,7 +12,6 @@ use zksync_types::{ web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{ utils::bytecode::bytes_to_be_words, @@ -195,7 +195,7 @@ impl TransactionData { let factory_deps_hashes = self .factory_deps .iter() - .map(|dep| h256_to_u256(hash_bytecode(dep))) + .map(|dep| BytecodeHash::for_bytecode(dep).value_u256()) .collect(); self.abi_encode_with_custom_factory_deps(factory_deps_hashes) } diff --git a/core/lib/multivm/src/vm_instance.rs b/core/lib/multivm/src/vm_instance.rs index e2f72bd24113..9de99a7eb116 100644 --- a/core/lib/multivm/src/vm_instance.rs +++ b/core/lib/multivm/src/vm_instance.rs @@ -14,6 +14,7 @@ use crate::{ VmMemoryMetrics, }, tracers::TracerDispatcher, + vm_fast::FastVmVersion, vm_latest::HistoryEnabled, }; @@ -132,7 +133,7 @@ impl LegacyVmInstance { l1_batch_env, system_env, storage_view, - crate::vm_m5::vm_instance::MultiVMSubversion::V1, + crate::vm_m5::vm_instance::MultiVmSubversion::V1, ); Self::VmM5(vm) } @@ -141,7 +142,7 @@ impl LegacyVmInstance { l1_batch_env, system_env, storage_view, - crate::vm_m5::vm_instance::MultiVMSubversion::V2, + crate::vm_m5::vm_instance::MultiVmSubversion::V2, ); Self::VmM5(vm) } @@ -150,7 +151,7 @@ impl LegacyVmInstance { l1_batch_env, system_env, storage_view, - crate::vm_m6::vm_instance::MultiVMSubversion::V1, + crate::vm_m6::vm_instance::MultiVmSubversion::V1, ); Self::VmM6(vm) } @@ -159,7 +160,7 @@ impl LegacyVmInstance { l1_batch_env, system_env, storage_view, - crate::vm_m6::vm_instance::MultiVMSubversion::V2, + crate::vm_m6::vm_instance::MultiVmSubversion::V2, ); Self::VmM6(vm) } @@ -194,7 +195,7 @@ impl LegacyVmInstance { l1_batch_env, system_env, storage_view, - crate::vm_latest::MultiVMSubversion::SmallBootloaderMemory, + crate::vm_latest::MultiVmSubversion::SmallBootloaderMemory, ); Self::Vm1_5_0(vm) } @@ -203,7 +204,7 @@ impl LegacyVmInstance { l1_batch_env, system_env, storage_view, - crate::vm_latest::MultiVMSubversion::IncreasedBootloaderMemory, + crate::vm_latest::MultiVmSubversion::IncreasedBootloaderMemory, ); Self::Vm1_5_0(vm) } @@ -212,7 +213,7 @@ impl LegacyVmInstance { l1_batch_env, system_env, storage_view, - crate::vm_latest::MultiVMSubversion::Gateway, + crate::vm_latest::MultiVmSubversion::Gateway, ); Self::Vm1_5_0(vm) } @@ -340,8 +341,5 @@ impl FastVmInstance { /// Checks whether the protocol version is supported by the fast VM. pub fn is_supported_by_fast_vm(protocol_version: ProtocolVersionId) -> bool { - matches!( - protocol_version.into(), - VmVersion::Vm1_5_0IncreasedBootloaderMemory - ) + FastVmVersion::try_from(VmVersion::from(protocol_version)).is_ok() } diff --git a/core/lib/snapshots_applier/Cargo.toml b/core/lib/snapshots_applier/Cargo.toml index 4ab0c86843ef..d107aac6d4c6 100644 --- a/core/lib/snapshots_applier/Cargo.toml +++ b/core/lib/snapshots_applier/Cargo.toml @@ -17,7 +17,6 @@ zksync_health_check.workspace = true zksync_types.workspace = true zksync_object_store.workspace = true zksync_web3_decl.workspace = true -zksync_utils.workspace = true vise.workspace = true diff --git a/core/lib/snapshots_applier/src/lib.rs b/core/lib/snapshots_applier/src/lib.rs index b4d24a0b1851..2c68b56ca5c6 100644 --- a/core/lib/snapshots_applier/src/lib.rs +++ b/core/lib/snapshots_applier/src/lib.rs @@ -13,6 +13,7 @@ use zksync_health_check::{Health, HealthStatus, HealthUpdater, ReactiveHealthChe use zksync_object_store::{ObjectStore, ObjectStoreError}; use zksync_types::{ api, + bytecode::BytecodeHash, snapshots::{ SnapshotFactoryDependencies, SnapshotHeader, SnapshotRecoveryStatus, SnapshotStorageLog, SnapshotStorageLogsChunk, SnapshotStorageLogsStorageKey, SnapshotVersion, @@ -20,7 +21,6 @@ use zksync_types::{ tokens::TokenInfo, L1BatchNumber, L2BlockNumber, StorageKey, H256, }; -use zksync_utils::bytecode::hash_bytecode; use zksync_web3_decl::{ client::{DynClient, L2}, error::{ClientRpcContext, EnrichedClientError, EnrichedClientResult}, @@ -800,9 +800,15 @@ impl<'a> SnapshotsApplier<'a> { // in underlying query, see `https://www.postgresql.org/docs/current/limits.html` // there were around 100 thousand contracts on mainnet, where this issue first manifested for chunk in factory_deps.factory_deps.chunks(1000) { + // TODO: bytecode hashing is ambiguous with EVM bytecodes let chunk_deps_hashmap: HashMap> = chunk .iter() - .map(|dep| (hash_bytecode(&dep.bytecode.0), dep.bytecode.0.clone())) + .map(|dep| { + ( + BytecodeHash::for_bytecode(&dep.bytecode.0).value(), + dep.bytecode.0.clone(), + ) + }) .collect(); storage .factory_deps_dal() diff --git a/core/lib/types/Cargo.toml b/core/lib/types/Cargo.toml index ffa9d219f084..325fe22209a7 100644 --- a/core/lib/types/Cargo.toml +++ b/core/lib/types/Cargo.toml @@ -13,7 +13,6 @@ categories.workspace = true [dependencies] # **IMPORTANT.** Please do not add dependency on `zksync_config` etc. This crate has a heavy dependency graph as is. zksync_system_constants.workspace = true -zksync_utils.workspace = true zksync_basic_types.workspace = true zksync_contracts.workspace = true zksync_mini_merkle_tree.workspace = true diff --git a/core/lib/types/src/abi.rs b/core/lib/types/src/abi.rs index 1ce709617ccf..92d4cb4c8612 100644 --- a/core/lib/types/src/abi.rs +++ b/core/lib/types/src/abi.rs @@ -1,10 +1,9 @@ use anyhow::Context as _; -use zksync_utils::bytecode::hash_bytecode; use crate::{ + bytecode::BytecodeHash, ethabi, ethabi::{ParamType, Token}, - h256_to_u256, transaction_request::TransactionRequest, web3, Address, H256, U256, }; @@ -357,7 +356,7 @@ impl Transaction { // verify data integrity let factory_deps_hashes: Vec<_> = factory_deps .iter() - .map(|b| h256_to_u256(hash_bytecode(b))) + .map(|b| BytecodeHash::for_bytecode(b).value_u256()) .collect(); anyhow::ensure!(tx.factory_deps == factory_deps_hashes); tx.hash() diff --git a/core/lib/types/src/api/state_override.rs b/core/lib/types/src/api/state_override.rs index f2986610840a..69025d1a1f78 100644 --- a/core/lib/types/src/api/state_override.rs +++ b/core/lib/types/src/api/state_override.rs @@ -1,10 +1,12 @@ use std::collections::HashMap; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; -use zksync_basic_types::{web3::Bytes, H256, U256}; -use zksync_utils::bytecode::{hash_bytecode, validate_bytecode, InvalidBytecodeError}; +use zksync_basic_types::{bytecode::BytecodeHash, web3::Bytes, H256, U256}; -use crate::Address; +use crate::{ + bytecode::{validate_bytecode, InvalidBytecodeError}, + Address, +}; /// Collection of overridden accounts. #[derive(Debug, Clone, Default, Serialize, Deserialize)] @@ -44,7 +46,7 @@ impl Bytecode { /// Returns the canonical hash of this bytecode. pub fn hash(&self) -> H256 { - hash_bytecode(&self.0 .0) + BytecodeHash::for_bytecode(&self.0 .0).value() } /// Converts this bytecode into bytes. diff --git a/core/lib/types/src/l1/mod.rs b/core/lib/types/src/l1/mod.rs index 0cc0f3b0e489..33225dd6b0c9 100644 --- a/core/lib/types/src/l1/mod.rs +++ b/core/lib/types/src/l1/mod.rs @@ -1,21 +1,21 @@ //! Definition of ZKsync network priority operations: operations initiated from the L1. -use std::convert::TryFrom; - use serde::{Deserialize, Serialize}; -use zksync_basic_types::{web3::Log, Address, L1BlockNumber, PriorityOpId, H256, U256}; -use zksync_utils::bytecode::hash_bytecode; use super::Transaction; use crate::{ - abi, address_to_u256, ethabi, h256_to_u256, + abi, address_to_u256, + bytecode::BytecodeHash, + ethabi, helpers::unix_timestamp_ms, l1::error::L1TxParseError, l2::TransactionType, priority_op_onchain_data::{PriorityOpOnchainData, PriorityOpOnchainMetadata}, tx::Execute, - u256_to_address, ExecuteTransactionCommon, PRIORITY_OPERATION_L2_TX_TYPE, - PROTOCOL_UPGRADE_TX_TYPE, + u256_to_address, + web3::Log, + Address, ExecuteTransactionCommon, L1BlockNumber, PriorityOpId, H256, + PRIORITY_OPERATION_L2_TX_TYPE, PROTOCOL_UPGRADE_TX_TYPE, U256, }; pub mod error; @@ -293,7 +293,7 @@ impl From for abi::NewPriorityRequest { signature: vec![], factory_deps: factory_deps .iter() - .map(|b| h256_to_u256(hash_bytecode(b))) + .map(|b| BytecodeHash::for_bytecode(b).value_u256()) .collect(), paymaster_input: vec![], reserved_dynamic: vec![], @@ -318,7 +318,7 @@ impl TryFrom for L1Tx { let factory_deps_hashes: Vec<_> = req .factory_deps .iter() - .map(|b| h256_to_u256(hash_bytecode(b))) + .map(|b| BytecodeHash::for_bytecode(b).value_u256()) .collect(); anyhow::ensure!(req.transaction.factory_deps == factory_deps_hashes); for item in &req.transaction.reserved[2..] { diff --git a/core/lib/types/src/lib.rs b/core/lib/types/src/lib.rs index 48ed7445ef5e..8ec98ec0571e 100644 --- a/core/lib/types/src/lib.rs +++ b/core/lib/types/src/lib.rs @@ -15,9 +15,9 @@ pub use protocol_upgrade::{ProtocolUpgrade, ProtocolVersion}; use serde::{Deserialize, Serialize}; pub use storage::*; pub use tx::Execute; +use zksync_basic_types::bytecode::BytecodeHash; pub use zksync_basic_types::{protocol_version::ProtocolVersionId, vm, *}; pub use zksync_crypto_primitives::*; -use zksync_utils::bytecode::hash_bytecode; use crate::{ l2::{L2Tx, TransactionType}, @@ -284,7 +284,7 @@ impl TryFrom for abi::Transaction { signature: vec![], factory_deps: factory_deps .iter() - .map(|b| h256_to_u256(hash_bytecode(b))) + .map(|b| BytecodeHash::for_bytecode(b).value_u256()) .collect(), paymaster_input: vec![], reserved_dynamic: vec![], @@ -315,7 +315,7 @@ impl TryFrom for abi::Transaction { signature: vec![], factory_deps: factory_deps .iter() - .map(|b| h256_to_u256(hash_bytecode(b))) + .map(|b| BytecodeHash::for_bytecode(b).value_u256()) .collect(), paymaster_input: vec![], reserved_dynamic: vec![], @@ -344,7 +344,7 @@ impl Transaction { } => { let factory_deps_hashes: Vec<_> = factory_deps .iter() - .map(|b| h256_to_u256(hash_bytecode(b))) + .map(|b| BytecodeHash::for_bytecode(b).value_u256()) .collect(); anyhow::ensure!(tx.factory_deps == factory_deps_hashes); for item in &tx.reserved[2..] { diff --git a/core/lib/types/src/transaction_request.rs b/core/lib/types/src/transaction_request.rs index 931615bad0fe..db66c6955bda 100644 --- a/core/lib/types/src/transaction_request.rs +++ b/core/lib/types/src/transaction_request.rs @@ -3,19 +3,18 @@ use std::convert::{TryFrom, TryInto}; use rlp::{DecoderError, Rlp, RlpStream}; use serde::{Deserialize, Serialize}; use thiserror::Error; -use zksync_basic_types::H256; use zksync_system_constants::{DEFAULT_L2_TX_GAS_PER_PUBDATA_BYTE, MAX_ENCODED_TX_SIZE}; -use zksync_utils::bytecode::{hash_bytecode, validate_bytecode, InvalidBytecodeError}; use super::{EIP_1559_TX_TYPE, EIP_2930_TX_TYPE, EIP_712_TX_TYPE}; use crate::{ + bytecode::{validate_bytecode, BytecodeHash, InvalidBytecodeError}, fee::Fee, l1::L1Tx, l2::{L2Tx, TransactionType}, u256_to_h256, web3::{keccak256, keccak256_concat, AccessList, Bytes}, Address, EIP712TypedStructure, Eip712Domain, L1TxCommonData, L2ChainId, Nonce, - PackedEthSignature, StructBuilder, LEGACY_TX_TYPE, U256, U64, + PackedEthSignature, StructBuilder, H256, LEGACY_TX_TYPE, U256, U64, }; /// Call contract request (eth_call / eth_estimateGas) @@ -174,7 +173,7 @@ impl CallRequestBuilder { } } -#[derive(Debug, Error, PartialEq)] +#[derive(Debug, Error)] pub enum SerializationTransactionError { #[error("transaction type is not supported")] UnknownTransactionFormat, @@ -353,7 +352,7 @@ impl EIP712TypedStructure for TransactionRequest { let factory_dep_hashes: Vec<_> = self .get_factory_deps() .into_iter() - .map(|dep| hash_bytecode(&dep)) + .map(|dep| BytecodeHash::for_bytecode(&dep).value()) .collect(); builder.add_member("factoryDeps", &factory_dep_hashes.as_slice()); @@ -1158,9 +1157,9 @@ mod tests { let decoded_tx = TransactionRequest::from_bytes(encoded_tx.as_slice(), L2ChainId::from(272)); - assert_eq!( - decoded_tx, - Err(SerializationTransactionError::WrongChainId(Some(270))) + assert_matches!( + decoded_tx.unwrap_err(), + SerializationTransactionError::WrongChainId(Some(270)) ); } @@ -1236,9 +1235,9 @@ mod tests { data.insert(0, EIP_1559_TX_TYPE); let decoded_tx = TransactionRequest::from_bytes(data.as_slice(), L2ChainId::from(270)); - assert_eq!( - decoded_tx, - Err(SerializationTransactionError::WrongChainId(Some(272))) + assert_matches!( + decoded_tx.unwrap_err(), + SerializationTransactionError::WrongChainId(Some(272)) ); } @@ -1276,9 +1275,9 @@ mod tests { data.insert(0, EIP_1559_TX_TYPE); let res = TransactionRequest::from_bytes(data.as_slice(), L2ChainId::from(270)); - assert_eq!( - res, - Err(SerializationTransactionError::AccessListsNotSupported) + assert_matches!( + res.unwrap_err(), + SerializationTransactionError::AccessListsNotSupported ); } @@ -1313,9 +1312,9 @@ mod tests { data.insert(0, EIP_2930_TX_TYPE); let res = TransactionRequest::from_bytes(data.as_slice(), L2ChainId::from(270)); - assert_eq!( - res, - Err(SerializationTransactionError::AccessListsNotSupported) + assert_matches!( + res.unwrap_err(), + SerializationTransactionError::AccessListsNotSupported ); } @@ -1341,7 +1340,7 @@ mod tests { }; let execute_tx2: Result = L2Tx::from_request(tx2, usize::MAX, true); - assert_eq!( + assert_matches!( execute_tx2.unwrap_err(), SerializationTransactionError::TooBigNonce ); @@ -1358,7 +1357,7 @@ mod tests { }; let execute_tx1: Result = L2Tx::from_request(tx1, usize::MAX, true); - assert_eq!( + assert_matches!( execute_tx1.unwrap_err(), SerializationTransactionError::MaxFeePerGasNotU64 ); @@ -1372,7 +1371,7 @@ mod tests { }; let execute_tx2: Result = L2Tx::from_request(tx2, usize::MAX, true); - assert_eq!( + assert_matches!( execute_tx2.unwrap_err(), SerializationTransactionError::MaxPriorityFeePerGasNotU64 ); @@ -1390,7 +1389,7 @@ mod tests { let execute_tx3: Result = L2Tx::from_request(tx3, usize::MAX, true); - assert_eq!( + assert_matches!( execute_tx3.unwrap_err(), SerializationTransactionError::MaxFeePerPubdataByteNotU64 ); diff --git a/core/lib/types/src/tx/execute.rs b/core/lib/types/src/tx/execute.rs index 0c3f63467cc4..f5cffef606eb 100644 --- a/core/lib/types/src/tx/execute.rs +++ b/core/lib/types/src/tx/execute.rs @@ -1,7 +1,7 @@ use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; +use zksync_basic_types::bytecode::BytecodeHash; use zksync_system_constants::CONTRACT_DEPLOYER_ADDRESS; -use zksync_utils::bytecode::hash_bytecode; use crate::{ ethabi, serde_wrappers::ZeroPrefixHexSerde, Address, EIP712TypedStructure, StructBuilder, H256, @@ -127,7 +127,7 @@ impl Execute { contract_bytecode: Vec, constructor_input: &[ethabi::Token], ) -> Self { - let bytecode_hash = hash_bytecode(&contract_bytecode); + let bytecode_hash = BytecodeHash::for_bytecode(&contract_bytecode).value(); Self { contract_address: Some(CONTRACT_DEPLOYER_ADDRESS), calldata: Self::encode_deploy_params_create( diff --git a/core/lib/utils/Cargo.toml b/core/lib/utils/Cargo.toml index 9ba286a7e493..216f3b12d426 100644 --- a/core/lib/utils/Cargo.toml +++ b/core/lib/utils/Cargo.toml @@ -11,15 +11,11 @@ keywords.workspace = true categories.workspace = true [dependencies] -zksync_basic_types.workspace = true -zk_evm.workspace = true zksync_vlog.workspace = true -const-decoder.workspace = true tokio = { workspace = true, features = ["time"] } tracing.workspace = true anyhow.workspace = true -thiserror.workspace = true futures.workspace = true reqwest = { workspace = true, features = ["blocking"] } serde_json.workspace = true diff --git a/core/lib/utils/src/lib.rs b/core/lib/utils/src/lib.rs index e2ab70695113..85618a2e61ef 100644 --- a/core/lib/utils/src/lib.rs +++ b/core/lib/utils/src/lib.rs @@ -1,6 +1,5 @@ //! Various helpers used in the ZKsync stack. -pub mod bytecode; pub mod env; pub mod http_with_retries; pub mod panic_extractor; diff --git a/core/lib/vm_executor/Cargo.toml b/core/lib/vm_executor/Cargo.toml index 06a531252c54..0402b7828e58 100644 --- a/core/lib/vm_executor/Cargo.toml +++ b/core/lib/vm_executor/Cargo.toml @@ -15,7 +15,6 @@ zksync_contracts.workspace = true zksync_dal.workspace = true zksync_types.workspace = true zksync_multivm.workspace = true -zksync_utils.workspace = true async-trait.workspace = true once_cell.workspace = true diff --git a/core/lib/vm_executor/src/batch/factory.rs b/core/lib/vm_executor/src/batch/factory.rs index de0db5f0bf75..76ef244401bd 100644 --- a/core/lib/vm_executor/src/batch/factory.rs +++ b/core/lib/vm_executor/src/batch/factory.rs @@ -18,7 +18,7 @@ use zksync_multivm::{ tracers::CallTracer, vm_fast, vm_latest::HistoryEnabled, - FastVmInstance, LegacyVmInstance, MultiVMTracer, + FastVmInstance, LegacyVmInstance, MultiVmTracer, }; use zksync_types::{commitment::PubdataParams, vm::FastVmMode, Transaction}; diff --git a/core/lib/vm_executor/src/oneshot/contracts.rs b/core/lib/vm_executor/src/oneshot/contracts.rs index d4e0a94f9178..cacab36cb1c2 100644 --- a/core/lib/vm_executor/src/oneshot/contracts.rs +++ b/core/lib/vm_executor/src/oneshot/contracts.rs @@ -26,7 +26,7 @@ impl ContractsKind for CallOrExecute {} /// Provider of [`BaseSystemContracts`] for oneshot execution. /// -/// The main implementation of this trait is [`MultiVMBaseSystemContracts`], which selects contracts +/// The main implementation of this trait is [`MultiVmBaseSystemContracts`], which selects contracts /// based on [`ProtocolVersionId`]. #[async_trait] pub trait BaseSystemContractsProvider: fmt::Debug + Send + Sync { @@ -46,7 +46,7 @@ pub trait BaseSystemContractsProvider: fmt::Debug + Send + Syn /// System contracts (bootloader and default account abstraction) for all supported VM versions. #[derive(Debug)] -pub struct MultiVMBaseSystemContracts { +pub struct MultiVmBaseSystemContracts { /// Contracts to be used for pre-virtual-blocks protocol versions. pre_virtual_blocks: BaseSystemContracts, /// Contracts to be used for post-virtual-blocks protocol versions. @@ -69,11 +69,11 @@ pub struct MultiVMBaseSystemContracts { vm_protocol_defense: BaseSystemContracts, /// Contracts to be used after the gateway upgrade gateway: BaseSystemContracts, - // We use `fn() -> C` marker so that the `MultiVMBaseSystemContracts` unconditionally implements `Send + Sync`. + // We use `fn() -> C` marker so that the `MultiVmBaseSystemContracts` unconditionally implements `Send + Sync`. _contracts_kind: PhantomData C>, } -impl MultiVMBaseSystemContracts { +impl MultiVmBaseSystemContracts { fn get_by_protocol_version( &self, version: ProtocolVersionId, @@ -120,7 +120,7 @@ impl MultiVMBaseSystemContracts { } } -impl MultiVMBaseSystemContracts { +impl MultiVmBaseSystemContracts { /// Returned system contracts (mainly the bootloader) are tuned to provide accurate execution metrics. pub fn load_estimate_gas_blocking() -> Self { Self { @@ -142,7 +142,7 @@ impl MultiVMBaseSystemContracts { } } -impl MultiVMBaseSystemContracts { +impl MultiVmBaseSystemContracts { /// Returned system contracts (mainly the bootloader) are tuned to provide better UX (e.g. revert messages). pub fn load_eth_call_blocking() -> Self { Self { @@ -165,7 +165,7 @@ impl MultiVMBaseSystemContracts { } #[async_trait] -impl BaseSystemContractsProvider for MultiVMBaseSystemContracts { +impl BaseSystemContractsProvider for MultiVmBaseSystemContracts { async fn base_system_contracts( &self, block_info: &ResolvedBlockInfo, diff --git a/core/lib/vm_executor/src/oneshot/mod.rs b/core/lib/vm_executor/src/oneshot/mod.rs index e95164c0fc87..0dfdb67bff52 100644 --- a/core/lib/vm_executor/src/oneshot/mod.rs +++ b/core/lib/vm_executor/src/oneshot/mod.rs @@ -29,7 +29,7 @@ use zksync_multivm::{ utils::adjust_pubdata_price_for_tx, vm_latest::{HistoryDisabled, HistoryEnabled}, zk_evm_latest::ethereum_types::U256, - FastVmInstance, HistoryMode, LegacyVmInstance, MultiVMTracer, + FastVmInstance, HistoryMode, LegacyVmInstance, MultiVmTracer, }; use zksync_types::{ block::pack_block_info, @@ -46,7 +46,7 @@ pub use self::{ block::{BlockInfo, ResolvedBlockInfo}, contracts::{ BaseSystemContractsProvider, CallOrExecute, ContractsKind, EstimateGas, - MultiVMBaseSystemContracts, + MultiVmBaseSystemContracts, }, env::OneshotEnvParameters, mock::MockOneshotExecutor, diff --git a/core/lib/vm_executor/src/oneshot/tests.rs b/core/lib/vm_executor/src/oneshot/tests.rs index 65d2ff3727c0..9649f5b49905 100644 --- a/core/lib/vm_executor/src/oneshot/tests.rs +++ b/core/lib/vm_executor/src/oneshot/tests.rs @@ -4,7 +4,6 @@ use assert_matches::assert_matches; use test_casing::{test_casing, Product}; use zksync_multivm::interface::storage::InMemoryStorage; use zksync_types::{ProtocolVersionId, H256}; -use zksync_utils::bytecode::hash_bytecode; use super::*; use crate::testonly::{ @@ -75,7 +74,7 @@ fn setting_up_nonce_and_balance_in_storage() { #[tokio::test] async fn inspecting_transfer(exec_mode: TxExecutionMode, fast_vm_mode: FastVmMode) { let tx = create_l2_transaction(1_000_000_000.into(), Nonce(0)); - let mut storage = InMemoryStorage::with_system_contracts(hash_bytecode); + let mut storage = InMemoryStorage::with_system_contracts(); storage.set_value( storage_key_for_eth_balance(&tx.initiator_account()), u256_to_h256(u64::MAX.into()), diff --git a/core/lib/vm_interface/src/storage/in_memory.rs b/core/lib/vm_interface/src/storage/in_memory.rs index d83f675cd54e..f756e7a6d76f 100644 --- a/core/lib/vm_interface/src/storage/in_memory.rs +++ b/core/lib/vm_interface/src/storage/in_memory.rs @@ -1,9 +1,9 @@ use std::collections::{hash_map::Entry, BTreeMap, HashMap}; use zksync_types::{ - block::DeployedContract, get_code_key, get_known_code_key, get_system_context_init_logs, - system_contracts::get_system_smart_contracts, L2ChainId, StorageKey, StorageLog, StorageValue, - H256, + block::DeployedContract, bytecode::BytecodeHash, get_code_key, get_known_code_key, + get_system_context_init_logs, system_contracts::get_system_smart_contracts, L2ChainId, + StorageKey, StorageLog, StorageValue, H256, }; use super::ReadStorage; @@ -21,29 +21,20 @@ pub struct InMemoryStorage { impl InMemoryStorage { /// Constructs a storage that contains system smart contracts. - pub fn with_system_contracts(bytecode_hasher: impl Fn(&[u8]) -> H256) -> Self { - Self::with_system_contracts_and_chain_id( - L2ChainId::from(IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID), - bytecode_hasher, - ) + pub fn with_system_contracts() -> Self { + Self::with_system_contracts_and_chain_id(L2ChainId::from( + IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID, + )) } /// Constructs a storage that contains system smart contracts (with a given chain id). - pub fn with_system_contracts_and_chain_id( - chain_id: L2ChainId, - bytecode_hasher: impl Fn(&[u8]) -> H256, - ) -> Self { - Self::with_custom_system_contracts_and_chain_id( - chain_id, - bytecode_hasher, - get_system_smart_contracts(false), - ) + pub fn with_system_contracts_and_chain_id(chain_id: L2ChainId) -> Self { + Self::with_custom_system_contracts_and_chain_id(chain_id, get_system_smart_contracts(false)) } /// Constructs a storage that contains custom system contracts (provided in a vector). pub fn with_custom_system_contracts_and_chain_id( chain_id: L2ChainId, - bytecode_hasher: impl Fn(&[u8]) -> H256, contracts: Vec, ) -> Self { let system_context_init_log = get_system_context_init_logs(chain_id); @@ -51,7 +42,7 @@ impl InMemoryStorage { let state_without_indices: BTreeMap<_, _> = contracts .iter() .flat_map(|contract| { - let bytecode_hash = bytecode_hasher(&contract.bytecode); + let bytecode_hash = BytecodeHash::for_bytecode(&contract.bytecode).value(); let deployer_code_key = get_code_key(contract.account_id.address()); let is_known_code_key = get_known_code_key(&bytecode_hash); @@ -72,7 +63,12 @@ impl InMemoryStorage { let factory_deps = contracts .into_iter() - .map(|contract| (bytecode_hasher(&contract.bytecode), contract.bytecode)) + .map(|contract| { + ( + BytecodeHash::for_bytecode(&contract.bytecode).value(), + contract.bytecode, + ) + }) .collect(); let last_enum_index_set = state.len() as u64; diff --git a/core/node/api_server/Cargo.toml b/core/node/api_server/Cargo.toml index d0723a9d23e7..70d343430a58 100644 --- a/core/node/api_server/Cargo.toml +++ b/core/node/api_server/Cargo.toml @@ -25,7 +25,6 @@ zksync_state.workspace = true zksync_system_constants.workspace = true zksync_metadata_calculator.workspace = true zksync_web3_decl = { workspace = true, features = ["server"] } -zksync_utils.workspace = true zksync_protobuf.workspace = true zksync_mini_merkle_tree.workspace = true zksync_multivm.workspace = true diff --git a/core/node/api_server/src/execution_sandbox/vm_metrics.rs b/core/node/api_server/src/execution_sandbox/vm_metrics.rs index 613475b6ef92..282d9bdf1b77 100644 --- a/core/node/api_server/src/execution_sandbox/vm_metrics.rs +++ b/core/node/api_server/src/execution_sandbox/vm_metrics.rs @@ -7,8 +7,7 @@ use zksync_multivm::{ interface::{TransactionExecutionMetrics, VmEvent, VmExecutionResultAndLogs}, utils::StorageWritesDeduplicator, }; -use zksync_types::H256; -use zksync_utils::bytecode::bytecode_len_in_bytes; +use zksync_types::{bytecode::BytecodeHash, H256}; use crate::utils::ReportFilter; @@ -149,7 +148,11 @@ pub(super) fn collect_tx_execution_metrics( .sum(); let published_bytecode_bytes = VmEvent::extract_published_bytecodes(&result.logs.events) .iter() - .map(|bytecode_hash| bytecode_len_in_bytes(*bytecode_hash)) + .map(|&bytecode_hash| { + BytecodeHash::try_from(bytecode_hash) + .expect("published unparseable bytecode hash") + .len_in_bytes() + }) .sum(); TransactionExecutionMetrics { diff --git a/core/node/api_server/src/tx_sender/mod.rs b/core/node/api_server/src/tx_sender/mod.rs index 180b53492839..91fb84ab8f17 100644 --- a/core/node/api_server/src/tx_sender/mod.rs +++ b/core/node/api_server/src/tx_sender/mod.rs @@ -33,7 +33,7 @@ use zksync_types::{ MAX_NEW_FACTORY_DEPS, U256, }; use zksync_vm_executor::oneshot::{ - CallOrExecute, EstimateGas, MultiVMBaseSystemContracts, OneshotEnvParameters, + CallOrExecute, EstimateGas, MultiVmBaseSystemContracts, OneshotEnvParameters, }; pub(super) use self::{gas_estimation::BinarySearchKind, result::SubmitTxError}; @@ -109,11 +109,11 @@ impl SandboxExecutorOptions { validation_computational_gas_limit: u32, ) -> anyhow::Result { let estimate_gas_contracts = - tokio::task::spawn_blocking(MultiVMBaseSystemContracts::load_estimate_gas_blocking) + tokio::task::spawn_blocking(MultiVmBaseSystemContracts::load_estimate_gas_blocking) .await .context("failed loading base contracts for gas estimation")?; let call_contracts = - tokio::task::spawn_blocking(MultiVMBaseSystemContracts::load_eth_call_blocking) + tokio::task::spawn_blocking(MultiVmBaseSystemContracts::load_eth_call_blocking) .await .context("failed loading base contracts for calls / tx execution")?; diff --git a/core/node/api_server/src/tx_sender/tests/gas_estimation.rs b/core/node/api_server/src/tx_sender/tests/gas_estimation.rs index 5e0c67477ffe..954792f915cc 100644 --- a/core/node/api_server/src/tx_sender/tests/gas_estimation.rs +++ b/core/node/api_server/src/tx_sender/tests/gas_estimation.rs @@ -7,10 +7,10 @@ use test_casing::{test_casing, Product}; use zksync_system_constants::CODE_ORACLE_ADDRESS; use zksync_types::{ api::state_override::{OverrideAccount, OverrideState}, + bytecode::BytecodeHash, web3::keccak256, K256PrivateKey, }; -use zksync_utils::bytecode::hash_bytecode; use super::*; use crate::{ @@ -216,7 +216,7 @@ async fn initial_estimate_for_code_oracle_tx() { // Add another contract that is never executed, but has a large bytecode. let huge_contact_address = Address::repeat_byte(23); let huge_contract_bytecode = vec![0_u8; 10_001 * 32]; - let huge_contract_bytecode_hash = hash_bytecode(&huge_contract_bytecode); + let huge_contract_bytecode_hash = BytecodeHash::for_bytecode(&huge_contract_bytecode).value(); let huge_contract_keccak_hash = H256(keccak256(&huge_contract_bytecode)); let state_override = StateBuilder::default() @@ -240,7 +240,7 @@ async fn initial_estimate_for_code_oracle_tx() { (*contract.account_id.address() == CODE_ORACLE_ADDRESS).then_some(&contract.bytecode) }) .expect("no code oracle"); - let code_oracle_bytecode_hash = hash_bytecode(code_oracle_bytecode); + let code_oracle_bytecode_hash = BytecodeHash::for_bytecode(code_oracle_bytecode).value(); let code_oracle_keccak_hash = H256(keccak256(code_oracle_bytecode)); let warm_bytecode_hashes = [ @@ -444,7 +444,7 @@ async fn estimating_gas_for_code_oracle_tx() { // Add another contract that is never executed, but has a large bytecode. let huge_contact_address = Address::repeat_byte(23); let huge_contract_bytecode = vec![0_u8; 10_001 * 32]; - let huge_contract_bytecode_hash = hash_bytecode(&huge_contract_bytecode); + let huge_contract_bytecode_hash = BytecodeHash::for_bytecode(&huge_contract_bytecode).value(); let huge_contract_keccak_hash = H256(keccak256(&huge_contract_bytecode)); let state_override = StateBuilder::default() diff --git a/core/node/api_server/src/web3/namespaces/eth.rs b/core/node/api_server/src/web3/namespaces/eth.rs index 588316ce70e4..2765de2c2892 100644 --- a/core/node/api_server/src/web3/namespaces/eth.rs +++ b/core/node/api_server/src/web3/namespaces/eth.rs @@ -6,6 +6,7 @@ use zksync_types::{ state_override::StateOverride, BlockId, BlockNumber, FeeHistory, GetLogsFilter, Transaction, TransactionId, TransactionReceipt, TransactionVariant, }, + bytecode::{trim_padded_evm_bytecode, BytecodeMarker}, l2::{L2Tx, TransactionType}, transaction_request::CallRequest, u256_to_h256, @@ -13,7 +14,6 @@ use zksync_types::{ web3::{self, Bytes, SyncInfo, SyncState}, AccountTreeId, L2BlockNumber, StorageKey, H256, L2_BASE_TOKEN_ADDRESS, U256, }; -use zksync_utils::bytecode::{prepare_evm_bytecode, BytecodeMarker}; use zksync_web3_decl::{ error::Web3Error, types::{Address, Block, Filter, FilterChanges, Log, U64}, @@ -404,7 +404,7 @@ impl EthNamespace { // Check if the bytecode is an EVM bytecode, and if so, pre-process it correspondingly. let marker = BytecodeMarker::new(contract_code.bytecode_hash); let prepared_bytecode = if marker == Some(BytecodeMarker::Evm) { - prepare_evm_bytecode(&contract_code.bytecode) + trim_padded_evm_bytecode(&contract_code.bytecode) .with_context(|| { format!( "malformed EVM bytecode at address {address:?}, hash = {:?}", diff --git a/core/node/api_server/src/web3/tests/mod.rs b/core/node/api_server/src/web3/tests/mod.rs index 9080c5ba413c..feac8eb8d17f 100644 --- a/core/node/api_server/src/web3/tests/mod.rs +++ b/core/node/api_server/src/web3/tests/mod.rs @@ -33,6 +33,10 @@ use zksync_system_constants::{ use zksync_types::{ api, block::{pack_block_info, L2BlockHasher, L2BlockHeader}, + bytecode::{ + testonly::{PROCESSED_EVM_BYTECODE, RAW_EVM_BYTECODE}, + BytecodeHash, + }, fee_model::{BatchFeeInput, FeeParams}, get_nonce_key, l2::L2Tx, @@ -45,10 +49,6 @@ use zksync_types::{ AccountTreeId, Address, L1BatchNumber, Nonce, ProtocolVersionId, StorageKey, StorageLog, H256, U256, U64, }; -use zksync_utils::bytecode::{ - hash_bytecode, hash_evm_bytecode, - testonly::{PROCESSED_EVM_BYTECODE, RAW_EVM_BYTECODE}, -}; use zksync_vm_executor::oneshot::MockOneshotExecutor; use zksync_web3_decl::{ client::{Client, DynClient, L2}, @@ -676,7 +676,7 @@ impl HttpTest for StorageAccessWithSnapshotRecovery { fn storage_initialization(&self) -> StorageInitialization { let address = Address::repeat_byte(1); let code_key = get_code_key(&address); - let code_hash = hash_bytecode(&[0; 32]); + let code_hash = BytecodeHash::for_bytecode(&[0; 32]).value(); let balance_key = storage_key_for_eth_balance(&address); let logs = vec![ StorageLog::new_write_log(code_key, code_hash), @@ -1171,7 +1171,7 @@ impl GetBytecodeTest { at_block: L2BlockNumber, address: Address, ) -> anyhow::Result<()> { - let evm_bytecode_hash = hash_evm_bytecode(RAW_EVM_BYTECODE); + let evm_bytecode_hash = BytecodeHash::for_evm_bytecode(RAW_EVM_BYTECODE).value(); let code_log = StorageLog::new_write_log(get_code_key(&address), evm_bytecode_hash); connection .storage_logs_dal() diff --git a/core/node/consensus/Cargo.toml b/core/node/consensus/Cargo.toml index 120d355da9a8..1d6b80f475e7 100644 --- a/core/node/consensus/Cargo.toml +++ b/core/node/consensus/Cargo.toml @@ -42,6 +42,7 @@ thiserror.workspace = true tracing.workspace = true tokio.workspace = true semver.workspace = true +vise.workspace = true [dev-dependencies] zksync_node_genesis.workspace = true diff --git a/core/node/consensus/src/en.rs b/core/node/consensus/src/en.rs index ec8d3c19b54a..e417b68cf2cb 100644 --- a/core/node/consensus/src/en.rs +++ b/core/node/consensus/src/en.rs @@ -17,13 +17,14 @@ use zksync_web3_decl::{ use super::{config, storage::Store, ConsensusConfig, ConsensusSecrets}; use crate::{ + metrics::METRICS, registry, storage::{self, ConnectionPool}, }; -/// If less than TEMPORARY_FETCHER_THRESHOLD certificates are missing, -/// the temporary fetcher will stop fetching blocks. -pub(crate) const TEMPORARY_FETCHER_THRESHOLD: u64 = 10; +/// Whenever more than FALLBACK_FETCHER_THRESHOLD certificates are missing, +/// the fallback fetcher is active. +pub(crate) const FALLBACK_FETCHER_THRESHOLD: u64 = 10; /// External node. pub(super) struct EN { @@ -115,11 +116,9 @@ impl EN { let store = store.clone(); async { let store = store; - self.temporary_block_fetcher(ctx, &store).await?; - tracing::info!( - "temporary block fetcher finished, switching to p2p fetching only" - ); - Ok(()) + self.fallback_block_fetcher(ctx, &store) + .await + .wrap("fallback_block_fetcher()") } }); @@ -179,7 +178,7 @@ impl EN { tracing::warn!("\ WARNING: this node is using ZKsync API synchronization, which will be deprecated soon. \ Please follow this instruction to switch to p2p synchronization: \ - https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/09_decentralization.md"); + https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/10_decentralization.md"); let res: ctx::Result<()> = scope::run!(ctx, |ctx, s| async { // Update sync state in the background. s.spawn_bg(self.fetch_state_loop(ctx)); @@ -191,7 +190,7 @@ impl EN { .new_payload_queue(ctx, actions, self.sync_state.clone()) .await .wrap("new_fetcher_cursor()")?; - self.fetch_blocks(ctx, &mut payload_queue, None).await + self.fetch_blocks(ctx, &mut payload_queue).await }) .await; match res { @@ -362,9 +361,14 @@ impl EN { } /// Fetches (with retries) the given block from the main node. - async fn fetch_block(&self, ctx: &ctx::Ctx, n: L2BlockNumber) -> ctx::Result { + async fn fetch_block( + &self, + ctx: &ctx::Ctx, + n: validator::BlockNumber, + ) -> ctx::Result { const RETRY_INTERVAL: time::Duration = time::Duration::seconds(5); - + let n = L2BlockNumber(n.0.try_into().context("overflow")?); + METRICS.fetch_block.inc(); loop { match ctx.wait(self.client.sync_l2_block(n, true)).await? { Ok(Some(block)) => return Ok(block.try_into()?), @@ -376,9 +380,8 @@ impl EN { } } - /// Fetches blocks from the main node directly, until the certificates - /// are backfilled. This allows for smooth transition from json RPC to p2p block syncing. - pub(crate) async fn temporary_block_fetcher( + /// Fetches blocks from the main node directly whenever the EN is lagging behind too much. + pub(crate) async fn fallback_block_fetcher( &self, ctx: &ctx::Ctx, store: &Store, @@ -386,66 +389,63 @@ impl EN { const MAX_CONCURRENT_REQUESTS: usize = 30; scope::run!(ctx, |ctx, s| async { let (send, mut recv) = ctx::channel::bounded(MAX_CONCURRENT_REQUESTS); - s.spawn(async { - let Some(mut next) = store.next_block(ctx).await? else { - return Ok(()); - }; - while store.persisted().borrow().next().0 + TEMPORARY_FETCHER_THRESHOLD < next.0 { - let n = L2BlockNumber(next.0.try_into().context("overflow")?); - self.sync_state.wait_for_main_node_block(ctx, n).await?; - send.send(ctx, s.spawn(self.fetch_block(ctx, n))).await?; + // TODO: metrics. + s.spawn::<()>(async { + let send = send; + let is_lagging = + |main| main >= store.persisted().borrow().next() + FALLBACK_FETCHER_THRESHOLD; + let mut next = store.next_block(ctx).await.wrap("next_block()")?; + loop { + // Wait until p2p syncing is lagging. + self.sync_state + .wait_for_main_node_block(ctx, is_lagging) + .await?; + // Determine the next block to fetch and wait for it to be available. + next = next.max(store.next_block(ctx).await.wrap("next_block()")?); + self.sync_state + .wait_for_main_node_block(ctx, |main| main >= next) + .await?; + // Fetch the block asynchronously. + send.send(ctx, s.spawn(self.fetch_block(ctx, next))).await?; next = next.next(); } - drop(send); - Ok(()) }); - while let Ok(block) = recv.recv_or_disconnected(ctx).await? { + loop { + let block = recv.recv(ctx).await?; store .queue_next_fetched_block(ctx, block.join(ctx).await?) .await .wrap("queue_next_fetched_block()")?; } - Ok(()) }) .await } - /// Fetches blocks from the main node in range `[cursor.next()..end)`. + /// Fetches blocks starting with `queue.next()`. async fn fetch_blocks( &self, ctx: &ctx::Ctx, queue: &mut storage::PayloadQueue, - end: Option, ) -> ctx::Result<()> { const MAX_CONCURRENT_REQUESTS: usize = 30; - let first = queue.next(); - let mut next = first; + let mut next = queue.next(); scope::run!(ctx, |ctx, s| async { let (send, mut recv) = ctx::channel::bounded(MAX_CONCURRENT_REQUESTS); - s.spawn(async { + s.spawn::<()>(async { let send = send; - while end.map_or(true, |end| next < end) { - let n = L2BlockNumber(next.0.try_into().context("overflow")?); - self.sync_state.wait_for_main_node_block(ctx, n).await?; - send.send(ctx, s.spawn(self.fetch_block(ctx, n))).await?; + loop { + self.sync_state + .wait_for_main_node_block(ctx, |main| main >= next) + .await?; + send.send(ctx, s.spawn(self.fetch_block(ctx, next))).await?; next = next.next(); } - Ok(()) }); - while end.map_or(true, |end| queue.next() < end) { + loop { let block = recv.recv(ctx).await?.join(ctx).await?; queue.send(block).await.context("queue.send()")?; } - Ok(()) }) - .await?; - // If fetched anything, wait for the last block to be stored persistently. - if first < queue.next() { - self.pool - .wait_for_payload(ctx, queue.next().prev().unwrap()) - .await - .wrap("wait_for_payload()")?; - } - Ok(()) + .await } } diff --git a/core/node/consensus/src/lib.rs b/core/node/consensus/src/lib.rs index 8bf078120aa9..d89aa5f5e829 100644 --- a/core/node/consensus/src/lib.rs +++ b/core/node/consensus/src/lib.rs @@ -9,6 +9,7 @@ mod abi; mod config; mod en; pub mod era; +mod metrics; mod mn; mod registry; mod storage; diff --git a/core/node/consensus/src/metrics.rs b/core/node/consensus/src/metrics.rs new file mode 100644 index 000000000000..f53bb9320917 --- /dev/null +++ b/core/node/consensus/src/metrics.rs @@ -0,0 +1,13 @@ +//! Consensus related metrics. + +#[derive(Debug, vise::Metrics)] +#[metrics(prefix = "zksync_node_consensus")] +pub(crate) struct Metrics { + /// Number of blocks that has been fetched via JSON-RPC. + /// It is used only as a fallback when the p2p syncing is disabled or falling behind. + /// so it shouldn't be increasing under normal circumstances if p2p syncing is enabled. + pub fetch_block: vise::Counter, +} + +#[vise::register] +pub(super) static METRICS: vise::Global = vise::Global::new(); diff --git a/core/node/consensus/src/storage/store.rs b/core/node/consensus/src/storage/store.rs index 154509e97b14..c42e78658dc2 100644 --- a/core/node/consensus/src/storage/store.rs +++ b/core/node/consensus/src/storage/store.rs @@ -114,14 +114,12 @@ impl Store { } /// Number of the next block to queue. - pub(crate) async fn next_block( - &self, - ctx: &ctx::Ctx, - ) -> ctx::OrCanceled> { + pub(crate) async fn next_block(&self, ctx: &ctx::Ctx) -> ctx::Result { Ok(sync::lock(ctx, &self.block_payloads) .await? .as_ref() - .map(|p| p.next())) + .context("payload_queue not set")? + .next()) } /// Queues the next block. diff --git a/core/node/consensus/src/testonly.rs b/core/node/consensus/src/testonly.rs index ef4226c915f0..faa895c86c71 100644 --- a/core/node/consensus/src/testonly.rs +++ b/core/node/consensus/src/testonly.rs @@ -45,10 +45,7 @@ use zksync_types::{ }; use zksync_web3_decl::client::{Client, DynClient, L2}; -use crate::{ - en, - storage::{ConnectionPool, Store}, -}; +use crate::{en, storage::ConnectionPool}; /// Fake StateKeeper for tests. #[derive(Debug)] @@ -413,40 +410,6 @@ impl StateKeeper { .await } - pub async fn run_temporary_fetcher( - self, - ctx: &ctx::Ctx, - client: Box>, - ) -> ctx::Result<()> { - scope::run!(ctx, |ctx, s| async { - let payload_queue = self - .pool - .connection(ctx) - .await - .wrap("connection()")? - .new_payload_queue(ctx, self.actions_sender, self.sync_state.clone()) - .await - .wrap("new_payload_queue()")?; - let (store, runner) = Store::new( - ctx, - self.pool.clone(), - Some(payload_queue), - Some(client.clone()), - ) - .await - .wrap("Store::new()")?; - s.spawn_bg(async { Ok(runner.run(ctx).await?) }); - en::EN { - pool: self.pool.clone(), - client, - sync_state: self.sync_state.clone(), - } - .temporary_block_fetcher(ctx, &store) - .await - }) - .await - } - /// Runs consensus node for the external node. pub async fn run_consensus( self, diff --git a/core/node/consensus/src/tests/mod.rs b/core/node/consensus/src/tests/mod.rs index 663ccab49904..efb8d14314c8 100644 --- a/core/node/consensus/src/tests/mod.rs +++ b/core/node/consensus/src/tests/mod.rs @@ -16,7 +16,7 @@ use zksync_types::ProtocolVersionId; use zksync_web3_decl::namespaces::EnNamespaceClient as _; use crate::{ - en::TEMPORARY_FETCHER_THRESHOLD, + en::FALLBACK_FETCHER_THRESHOLD, mn::run_main_node, storage::{ConnectionPool, Store}, testonly, @@ -665,7 +665,7 @@ async fn test_p2p_fetcher_backfill_certs(from_snapshot: bool, version: ProtocolV // Test temporary fetcher fetching blocks if a lot of certs are missing. #[test_casing(4, Product((FROM_SNAPSHOT,VERSIONS)))] #[tokio::test] -async fn test_temporary_fetcher(from_snapshot: bool, version: ProtocolVersionId) { +async fn test_fallback_fetcher(from_snapshot: bool, version: ProtocolVersionId) { zksync_concurrency::testonly::abort_on_panic(); let ctx = &ctx::test_root(&ctx::AffineClock::new(10.)); let rng = &mut ctx.rng(); @@ -705,7 +705,7 @@ async fn test_temporary_fetcher(from_snapshot: bool, version: ProtocolVersionId) s.spawn_bg(runner.run(ctx)); s.spawn_bg(node.run_fetcher(ctx, client.clone())); validator - .push_random_blocks(rng, account, TEMPORARY_FETCHER_THRESHOLD as usize + 1) + .push_random_blocks(rng, account, FALLBACK_FETCHER_THRESHOLD as usize + 1) .await; node_pool .wait_for_payload(ctx, validator.last_block()) @@ -715,58 +715,7 @@ async fn test_temporary_fetcher(from_snapshot: bool, version: ProtocolVersionId) .await .unwrap(); - tracing::info!( - "Run p2p fetcher. Blocks should be fetched by the temporary fetcher anyway." - ); - scope::run!(ctx, |ctx, s| async { - let (node, runner) = testonly::StateKeeper::new(ctx, node_pool.clone()).await?; - s.spawn_bg(runner.run(ctx)); - s.spawn_bg(node.run_consensus(ctx, client.clone(), node_cfg.clone())); - validator.push_random_blocks(rng, account, 5).await; - node_pool - .wait_for_payload(ctx, validator.last_block()) - .await?; - Ok(()) - }) - .await - .unwrap(); - Ok(()) - }) - .await - .unwrap(); -} - -// Test that temporary fetcher terminates once enough blocks have certs. -#[test_casing(4, Product((FROM_SNAPSHOT,VERSIONS)))] -#[tokio::test] -async fn test_temporary_fetcher_termination(from_snapshot: bool, version: ProtocolVersionId) { - zksync_concurrency::testonly::abort_on_panic(); - let ctx = &ctx::test_root(&ctx::AffineClock::new(10.)); - let rng = &mut ctx.rng(); - let setup = Setup::new(rng, 1); - let validator_cfg = testonly::new_configs(rng, &setup, 0)[0].clone(); - let node_cfg = validator_cfg.new_fullnode(rng); - let account = &mut Account::random(); - - scope::run!(ctx, |ctx, s| async { - tracing::info!("Spawn validator."); - let validator_pool = ConnectionPool::test(from_snapshot, version).await; - let (mut validator, runner) = - testonly::StateKeeper::new(ctx, validator_pool.clone()).await?; - s.spawn_bg(runner.run(ctx)); - s.spawn_bg(run_main_node( - ctx, - validator_cfg.config.clone(), - validator_cfg.secrets.clone(), - validator_pool.clone(), - )); - // API server needs at least 1 L1 batch to start. - validator.seal_batch().await; - let client = validator.connect(ctx).await?; - - let node_pool = ConnectionPool::test(from_snapshot, version).await; - - // Run the EN so the consensus is initialized on EN and wait for it to sync. + tracing::info!("Run p2p fetcher. Blocks should be fetched by the fallback fetcher anyway."); scope::run!(ctx, |ctx, s| async { let (node, runner) = testonly::StateKeeper::new(ctx, node_pool.clone()).await?; s.spawn_bg(runner.run(ctx)); @@ -779,12 +728,6 @@ async fn test_temporary_fetcher_termination(from_snapshot: bool, version: Protoc }) .await .unwrap(); - - // Run the temporary fetcher. It should terminate immediately, since EN is synced. - let (node, runner) = testonly::StateKeeper::new(ctx, node_pool.clone()).await?; - s.spawn_bg(runner.run(ctx)); - node.run_temporary_fetcher(ctx, client).await?; - Ok(()) }) .await diff --git a/core/node/consensus/src/vm.rs b/core/node/consensus/src/vm.rs index cbd4918dcee1..81d26ebc3758 100644 --- a/core/node/consensus/src/vm.rs +++ b/core/node/consensus/src/vm.rs @@ -8,7 +8,7 @@ use zksync_state::PostgresStorage; use zksync_system_constants::DEFAULT_L2_TX_GAS_PER_PUBDATA_BYTE; use zksync_types::{ethabi, fee::Fee, l2::L2Tx, AccountTreeId, L2ChainId, Nonce, U256}; use zksync_vm_executor::oneshot::{ - CallOrExecute, MainOneshotExecutor, MultiVMBaseSystemContracts, OneshotEnvParameters, + CallOrExecute, MainOneshotExecutor, MultiVmBaseSystemContracts, OneshotEnvParameters, }; use zksync_vm_interface::{ executor::OneshotExecutor, storage::StorageWithOverrides, ExecutionResult, @@ -29,7 +29,7 @@ impl VM { /// Constructs a new `VM` instance. pub async fn new(pool: ConnectionPool) -> Self { let base_system_contracts = - scope::wait_blocking(MultiVMBaseSystemContracts::load_eth_call_blocking).await; + scope::wait_blocking(MultiVmBaseSystemContracts::load_eth_call_blocking).await; Self { pool, // L2 chain ID and fee account don't seem to matter for calls, hence the use of default values. diff --git a/core/node/contract_verification_server/Cargo.toml b/core/node/contract_verification_server/Cargo.toml index 038347debc64..e6a81fe6026a 100644 --- a/core/node/contract_verification_server/Cargo.toml +++ b/core/node/contract_verification_server/Cargo.toml @@ -13,7 +13,6 @@ categories.workspace = true [dependencies] zksync_dal.workspace = true zksync_types.workspace = true -zksync_utils.workspace = true vise.workspace = true anyhow.workspace = true diff --git a/core/node/contract_verification_server/src/api_impl.rs b/core/node/contract_verification_server/src/api_impl.rs index 94be65673bad..b0336fd284b6 100644 --- a/core/node/contract_verification_server/src/api_impl.rs +++ b/core/node/contract_verification_server/src/api_impl.rs @@ -9,12 +9,12 @@ use axum::{ }; use zksync_dal::{CoreDal, DalError}; use zksync_types::{ + bytecode::BytecodeMarker, contract_verification_api::{ CompilerVersions, VerificationIncomingRequest, VerificationInfo, VerificationRequestStatus, }, Address, }; -use zksync_utils::bytecode::BytecodeMarker; use super::{api_decl::RestApi, metrics::METRICS}; diff --git a/core/node/contract_verification_server/src/tests.rs b/core/node/contract_verification_server/src/tests.rs index b7b0d3e8efb4..c5c1d88b3d0c 100644 --- a/core/node/contract_verification_server/src/tests.rs +++ b/core/node/contract_verification_server/src/tests.rs @@ -12,10 +12,10 @@ use tower::ServiceExt; use zksync_dal::{Connection, Core, CoreDal}; use zksync_node_test_utils::create_l2_block; use zksync_types::{ - contract_verification_api::CompilerVersions, get_code_key, Address, L2BlockNumber, - ProtocolVersion, StorageLog, + bytecode::{BytecodeHash, BytecodeMarker}, + contract_verification_api::CompilerVersions, + get_code_key, Address, L2BlockNumber, ProtocolVersion, StorageLog, }; -use zksync_utils::bytecode::{hash_bytecode, hash_evm_bytecode, BytecodeMarker}; use super::*; use crate::api_impl::ApiError; @@ -53,8 +53,8 @@ async fn mock_deploy_contract( kind: BytecodeMarker, ) { let bytecode_hash = match kind { - BytecodeMarker::EraVm => hash_bytecode(&[0; 32]), - BytecodeMarker::Evm => hash_evm_bytecode(&[0; 96]), + BytecodeMarker::EraVm => BytecodeHash::for_bytecode(&[0; 32]).value(), + BytecodeMarker::Evm => BytecodeHash::for_evm_bytecode(&[0; 96]).value(), }; let deploy_log = StorageLog::new_write_log(get_code_key(&address), bytecode_hash); storage diff --git a/core/node/genesis/Cargo.toml b/core/node/genesis/Cargo.toml index 71c4c45e9e38..d625d7186bdf 100644 --- a/core/node/genesis/Cargo.toml +++ b/core/node/genesis/Cargo.toml @@ -20,7 +20,6 @@ zksync_contracts.workspace = true zksync_eth_client.workspace = true zksync_merkle_tree.workspace = true zksync_system_constants.workspace = true -zksync_utils.workspace = true tokio = { workspace = true, features = ["time"] } anyhow.workspace = true diff --git a/core/node/genesis/src/lib.rs b/core/node/genesis/src/lib.rs index 03f51d5c5fc3..0a0e77d97f95 100644 --- a/core/node/genesis/src/lib.rs +++ b/core/node/genesis/src/lib.rs @@ -17,6 +17,7 @@ use zksync_multivm::utils::get_max_gas_per_pubdata_byte; use zksync_system_constants::PRIORITY_EXPIRATION; use zksync_types::{ block::{BlockGasCount, DeployedContract, L1BatchHeader, L2BlockHasher, L2BlockHeader}, + bytecode::BytecodeHash, commitment::{CommitmentInput, L1BatchCommitment}, fee_model::BatchFeeInput, protocol_upgrade::decode_set_chain_id_event, @@ -27,7 +28,6 @@ use zksync_types::{ AccountTreeId, Address, Bloom, L1BatchNumber, L1ChainId, L2BlockNumber, L2ChainId, ProtocolVersion, ProtocolVersionId, StorageKey, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::utils::{ add_eth_token, get_deduped_log_queries, get_storage_logs, @@ -447,7 +447,12 @@ pub async fn create_genesis_l1_batch( let factory_deps = system_contracts .iter() - .map(|c| (hash_bytecode(&c.bytecode), c.bytecode.clone())) + .map(|c| { + ( + BytecodeHash::for_bytecode(&c.bytecode).value(), + c.bytecode.clone(), + ) + }) .collect(); insert_base_system_contracts_to_factory_deps(&mut transaction, base_system_contracts).await?; diff --git a/core/node/genesis/src/utils.rs b/core/node/genesis/src/utils.rs index d89d7475e84b..a51f49a166a2 100644 --- a/core/node/genesis/src/utils.rs +++ b/core/node/genesis/src/utils.rs @@ -5,11 +5,12 @@ use zksync_contracts::BaseSystemContracts; use zksync_dal::{Connection, Core, CoreDal}; use zksync_multivm::{ circuit_sequencer_api_latest::sort_storage_access::sort_storage_access_queries, - zk_evm_latest::aux_structures::{LogQuery as MultiVmLogQuery, Timestamp as MultiVMTimestamp}, + zk_evm_latest::aux_structures::{LogQuery as MultiVmLogQuery, Timestamp as MultiVmTimestamp}, }; use zksync_system_constants::{DEFAULT_ERA_CHAIN_ID, ETHEREUM_ADDRESS}; use zksync_types::{ block::{DeployedContract, L1BatchTreeData}, + bytecode::BytecodeHash, commitment::L1BatchCommitment, get_code_key, get_known_code_key, get_system_context_init_logs, h256_to_u256, tokens::{TokenInfo, TokenMetadata}, @@ -17,7 +18,6 @@ use zksync_types::{ zk_evm_types::{LogQuery, Timestamp}, AccountTreeId, L1BatchNumber, L2BlockNumber, L2ChainId, StorageKey, StorageLog, H256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::GenesisError; @@ -51,7 +51,7 @@ pub(super) fn get_storage_logs(system_contracts: &[DeployedContract]) -> Vec = system_contracts .iter() .map(|contract| { - let hash = hash_bytecode(&contract.bytecode); + let hash = BytecodeHash::for_bytecode(&contract.bytecode).value(); let known_code_key = get_known_code_key(&hash); let marked_known_value = H256::from_low_u64_be(1u64); @@ -63,7 +63,7 @@ pub(super) fn get_storage_logs(system_contracts: &[DeployedContract]) -> Vec = system_contracts .iter() .map(|contract| { - let hash = hash_bytecode(&contract.bytecode); + let hash = BytecodeHash::for_bytecode(&contract.bytecode).value(); let code_key = get_code_key(contract.account_id.address()); StorageLog::new_write_log(code_key, hash) }) @@ -84,7 +84,7 @@ pub(super) fn get_deduped_log_queries(storage_logs: &[StorageLog]) -> Vec> { .with_arg("hash", &hash) .await?; if let Some(bytecode) = &bytecode { - let actual_bytecode_hash = zksync_utils::bytecode::hash_bytecode(bytecode); + let actual_bytecode_hash = BytecodeHash::for_bytecode(bytecode).value(); if actual_bytecode_hash != hash { return Err(EnrichedClientError::custom( "Got invalid base system contract bytecode from main node", diff --git a/core/node/node_sync/src/sync_state.rs b/core/node/node_sync/src/sync_state.rs index f8a2fe00ec09..1ffec757c9b1 100644 --- a/core/node/node_sync/src/sync_state.rs +++ b/core/node/node_sync/src/sync_state.rs @@ -4,6 +4,7 @@ use async_trait::async_trait; use serde::Serialize; use tokio::sync::watch; use zksync_concurrency::{ctx, sync}; +use zksync_consensus_roles::validator; use zksync_dal::{ConnectionPool, Core, CoreDal}; use zksync_health_check::{CheckHealth, Health, HealthStatus}; use zksync_shared_metrics::EN_METRICS; @@ -50,18 +51,20 @@ impl SyncState { .unwrap(); } + /// Waits until the main node block is greater or equal to the given block number. + /// Returns the current main node block number. pub async fn wait_for_main_node_block( &self, ctx: &ctx::Ctx, - want: L2BlockNumber, - ) -> ctx::OrCanceled<()> { - sync::wait_for( - ctx, - &mut self.0.subscribe(), - |inner| matches!(inner.main_node_block, Some(got) if got >= want), - ) - .await?; - Ok(()) + pred: impl Fn(validator::BlockNumber) -> bool, + ) -> ctx::OrCanceled { + sync::wait_for_some(ctx, &mut self.0.subscribe(), |inner| { + inner + .main_node_block + .map(|n| validator::BlockNumber(n.0.into())) + .filter(|n| pred(*n)) + }) + .await } pub fn set_main_node_block(&self, block: L2BlockNumber) { diff --git a/core/node/state_keeper/Cargo.toml b/core/node/state_keeper/Cargo.toml index 75d7c9f1e943..ff17ec2268ab 100644 --- a/core/node/state_keeper/Cargo.toml +++ b/core/node/state_keeper/Cargo.toml @@ -22,7 +22,6 @@ zksync_mempool.workspace = true zksync_shared_metrics.workspace = true zksync_config.workspace = true zksync_node_fee_model.workspace = true -zksync_utils.workspace = true zksync_contracts.workspace = true zksync_protobuf.workspace = true zksync_test_account.workspace = true @@ -32,7 +31,6 @@ zksync_vm_executor.workspace = true zksync_system_constants.workspace = true zksync_base_token_adjuster.workspace = true - anyhow.workspace = true async-trait.workspace = true tokio = { workspace = true, features = ["time"] } diff --git a/core/node/state_keeper/src/io/tests/mod.rs b/core/node/state_keeper/src/io/tests/mod.rs index 4ea3460e6e30..5a44bf71ad39 100644 --- a/core/node/state_keeper/src/io/tests/mod.rs +++ b/core/node/state_keeper/src/io/tests/mod.rs @@ -14,13 +14,13 @@ use zksync_node_test_utils::prepare_recovery_snapshot; use zksync_system_constants::KNOWN_CODES_STORAGE_ADDRESS; use zksync_types::{ block::{BlockGasCount, L2BlockHasher}, + bytecode::BytecodeHash, commitment::{L1BatchCommitmentMode, PubdataParams}, fee_model::{BatchFeeInput, PubdataIndependentBatchFeeModelInput}, l2::L2Tx, AccountTreeId, Address, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersion, ProtocolVersionId, StorageKey, TransactionTimeRangeConstraint, H256, U256, }; -use zksync_utils::bytecode::{hash_bytecode, hash_evm_bytecode}; use self::tester::Tester; use crate::{ @@ -438,13 +438,19 @@ async fn processing_dynamic_factory_deps_when_sealing_l2_block() { let static_factory_deps: Vec<_> = (0_u8..10) .map(|byte| { let era_bytecode = vec![byte; 32]; - (hash_bytecode(&era_bytecode), era_bytecode) + ( + BytecodeHash::for_bytecode(&era_bytecode).value(), + era_bytecode, + ) }) .collect(); let dynamic_factory_deps: Vec<_> = (0_u8..10) .map(|byte| { let evm_bytecode = vec![byte; 96]; - (hash_evm_bytecode(&evm_bytecode), evm_bytecode) + ( + BytecodeHash::for_evm_bytecode(&evm_bytecode).value(), + evm_bytecode, + ) }) .collect(); let mut all_factory_deps = static_factory_deps.clone(); diff --git a/core/node/state_keeper/src/updates/l2_block_updates.rs b/core/node/state_keeper/src/updates/l2_block_updates.rs index 6faa098d40a2..d258f8eeac0b 100644 --- a/core/node/state_keeper/src/updates/l2_block_updates.rs +++ b/core/node/state_keeper/src/updates/l2_block_updates.rs @@ -9,10 +9,10 @@ use zksync_multivm::{ }; use zksync_types::{ block::{BlockGasCount, L2BlockHasher}, + bytecode::BytecodeHash, l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, L2BlockNumber, ProtocolVersionId, StorageLogWithPreviousValue, Transaction, H256, }; -use zksync_utils::bytecode::hash_bytecode; use crate::metrics::KEEPER_METRICS; @@ -119,7 +119,12 @@ impl L2BlockUpdates { let factory_deps = &tx.execute.factory_deps; let mut tx_factory_deps: HashMap<_, _> = factory_deps .iter() - .map(|bytecode| (hash_bytecode(bytecode), bytecode.clone())) + .map(|bytecode| { + ( + BytecodeHash::for_bytecode(bytecode).value(), + bytecode.clone(), + ) + }) .collect(); // Ensure that *dynamic* factory deps (ones that may be created when executing EVM contracts) // are added into the lookup map as well. diff --git a/core/node/vm_runner/Cargo.toml b/core/node/vm_runner/Cargo.toml index 9c235ad6b291..ef479df17e30 100644 --- a/core/node/vm_runner/Cargo.toml +++ b/core/node/vm_runner/Cargo.toml @@ -17,7 +17,6 @@ zksync_dal.workspace = true zksync_contracts.workspace = true zksync_state.workspace = true zksync_storage.workspace = true -zksync_utils.workspace = true zksync_prover_interface.workspace = true zksync_object_store.workspace = true zksync_vm_executor.workspace = true diff --git a/core/node/vm_runner/src/tests/mod.rs b/core/node/vm_runner/src/tests/mod.rs index d56c70e5808d..97b679695d2a 100644 --- a/core/node/vm_runner/src/tests/mod.rs +++ b/core/node/vm_runner/src/tests/mod.rs @@ -12,6 +12,7 @@ use zksync_node_test_utils::{ use zksync_test_account::Account; use zksync_types::{ block::{L1BatchHeader, L2BlockHasher}, + bytecode::BytecodeHash, fee::Fee, get_intrinsic_constants, h256_to_u256, l2::L2Tx, @@ -20,7 +21,6 @@ use zksync_types::{ AccountTreeId, Address, Execute, L1BatchNumber, L2BlockNumber, ProtocolVersionId, StorageKey, StorageLog, StorageLogKind, StorageValue, H160, H256, L2_BASE_TOKEN_ADDRESS, U256, }; -use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::{ tracer::ValidationTraces, L1BatchEnv, L2BlockEnv, SystemEnv, TransactionExecutionMetrics, }; @@ -327,7 +327,7 @@ async fn store_l1_batches( header.used_contract_hashes = genesis_params .system_contracts() .iter() - .map(|contract| hash_bytecode(&contract.bytecode)) + .map(|contract| BytecodeHash::for_bytecode(&contract.bytecode).value()) .chain([genesis_params.base_system_contracts().hashes().default_aa]) .chain(genesis_params.base_system_contracts().hashes().evm_emulator) .map(h256_to_u256) diff --git a/core/tests/loadnext/src/sdk/operations/deploy_contract.rs b/core/tests/loadnext/src/sdk/operations/deploy_contract.rs index 67e877ae8efb..cac49559c468 100644 --- a/core/tests/loadnext/src/sdk/operations/deploy_contract.rs +++ b/core/tests/loadnext/src/sdk/operations/deploy_contract.rs @@ -1,8 +1,8 @@ use zksync_eth_signer::EthereumSigner; use zksync_types::{ - l2::L2Tx, transaction_request::PaymasterParams, Execute, Nonce, CONTRACT_DEPLOYER_ADDRESS, U256, + bytecode::BytecodeHash, l2::L2Tx, transaction_request::PaymasterParams, Execute, Nonce, + CONTRACT_DEPLOYER_ADDRESS, U256, }; -use zksync_utils::bytecode::hash_bytecode; use zksync_web3_decl::namespaces::EthNamespaceClient; use crate::sdk::{ @@ -60,7 +60,7 @@ where None => Nonce(self.wallet.get_nonce().await?), }; - let main_contract_hash = hash_bytecode(&bytecode); + let main_contract_hash = BytecodeHash::for_bytecode(&bytecode).value(); let execute_calldata = Execute::encode_deploy_params_create(Default::default(), main_contract_hash, calldata); @@ -141,7 +141,7 @@ where .unwrap_or_default(); let calldata = self.calldata.clone().unwrap_or_default(); - let main_contract_hash = hash_bytecode(&bytecode); + let main_contract_hash = BytecodeHash::for_bytecode(&bytecode).value(); let mut factory_deps = self.factory_deps.clone().unwrap_or_default(); factory_deps.push(bytecode); let l2_tx = L2Tx::new( diff --git a/core/tests/test_account/Cargo.toml b/core/tests/test_account/Cargo.toml index 0dda4f8ac777..9d32d4951f54 100644 --- a/core/tests/test_account/Cargo.toml +++ b/core/tests/test_account/Cargo.toml @@ -13,7 +13,6 @@ categories.workspace = true [dependencies] zksync_types.workspace = true zksync_system_constants.workspace = true -zksync_utils.workspace = true zksync_eth_signer.workspace = true zksync_contracts.workspace = true diff --git a/core/tests/test_account/src/lib.rs b/core/tests/test_account/src/lib.rs index b8c79923a4e8..6c4e57087326 100644 --- a/core/tests/test_account/src/lib.rs +++ b/core/tests/test_account/src/lib.rs @@ -8,11 +8,10 @@ use zksync_system_constants::{ REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE, }; use zksync_types::{ - abi, address_to_u256, fee::Fee, h256_to_u256, l2::L2Tx, utils::deployed_address_create, - Address, Execute, K256PrivateKey, L2ChainId, Nonce, Transaction, H256, - PRIORITY_OPERATION_L2_TX_TYPE, U256, + abi, address_to_u256, bytecode::BytecodeHash, fee::Fee, l2::L2Tx, + utils::deployed_address_create, Address, Execute, K256PrivateKey, L2ChainId, Nonce, + Transaction, H256, PRIORITY_OPERATION_L2_TX_TYPE, U256, }; -use zksync_utils::bytecode::hash_bytecode; pub const L1_TEST_GAS_PER_PUBDATA_BYTE: u32 = 800; const BASE_FEE: u64 = 2_000_000_000; @@ -124,7 +123,7 @@ impl Account { let contract_function = deployer.function("create").unwrap(); let calldata = calldata.map(ethabi::encode); - let code_hash = hash_bytecode(code); + let code_hash = BytecodeHash::for_bytecode(code).value(); let params = [ Token::FixedBytes(vec![0u8; 32]), Token::FixedBytes(code_hash.0.to_vec()), @@ -185,7 +184,7 @@ impl Account { signature: vec![], factory_deps: factory_deps .iter() - .map(|b| h256_to_u256(hash_bytecode(b))) + .map(|b| BytecodeHash::for_bytecode(b).value_u256()) .collect(), paymaster_input: vec![], reserved_dynamic: vec![], diff --git a/core/tests/vm-benchmark/Cargo.toml b/core/tests/vm-benchmark/Cargo.toml index 892bcf1c1051..bbcc30f961fd 100644 --- a/core/tests/vm-benchmark/Cargo.toml +++ b/core/tests/vm-benchmark/Cargo.toml @@ -9,7 +9,6 @@ publish = false zksync_contracts.workspace = true zksync_multivm.workspace = true zksync_types.workspace = true -zksync_utils.workspace = true zksync_vlog.workspace = true zksync_vm2.workspace = true diff --git a/core/tests/vm-benchmark/src/transaction.rs b/core/tests/vm-benchmark/src/transaction.rs index c625018fb9bf..e5be25545377 100644 --- a/core/tests/vm-benchmark/src/transaction.rs +++ b/core/tests/vm-benchmark/src/transaction.rs @@ -3,6 +3,7 @@ pub use zksync_contracts::test_contracts::LoadnextContractExecutionParams as Loa use zksync_contracts::{deployer_contract, TestContract}; use zksync_multivm::utils::get_max_gas_per_pubdata_byte; use zksync_types::{ + bytecode::BytecodeHash, ethabi::{encode, Token}, fee::Fee, l2::L2Tx, @@ -10,7 +11,6 @@ use zksync_types::{ Address, K256PrivateKey, L2ChainId, Nonce, ProtocolVersionId, Transaction, CONTRACT_DEPLOYER_ADDRESS, H256, U256, }; -use zksync_utils::bytecode::hash_bytecode; const LOAD_TEST_MAX_READS: usize = 3000; @@ -37,7 +37,7 @@ pub fn get_deploy_tx_with_gas_limit(code: &[u8], gas_limit: u32, nonce: u32) -> salt[28..32].copy_from_slice(&nonce.to_be_bytes()); let params = [ Token::FixedBytes(salt), - Token::FixedBytes(hash_bytecode(code).0.to_vec()), + Token::FixedBytes(BytecodeHash::for_bytecode(code).value().0.to_vec()), Token::Bytes([].to_vec()), ]; let calldata = CREATE_FUNCTION_SIGNATURE @@ -96,7 +96,12 @@ pub fn get_load_test_deploy_tx() -> Transaction { let calldata = [Token::Uint(LOAD_TEST_MAX_READS.into())]; let params = [ Token::FixedBytes(vec![0_u8; 32]), - Token::FixedBytes(hash_bytecode(&LOAD_TEST_CONTRACT.bytecode).0.to_vec()), + Token::FixedBytes( + BytecodeHash::for_bytecode(&LOAD_TEST_CONTRACT.bytecode) + .value() + .0 + .to_vec(), + ), Token::Bytes(encode(&calldata)), ]; let create_calldata = CREATE_FUNCTION_SIGNATURE diff --git a/core/tests/vm-benchmark/src/vm.rs b/core/tests/vm-benchmark/src/vm.rs index e082b9c24da2..a855dfafb04e 100644 --- a/core/tests/vm-benchmark/src/vm.rs +++ b/core/tests/vm-benchmark/src/vm.rs @@ -18,14 +18,13 @@ use zksync_types::{ utils::storage_key_for_eth_balance, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, Transaction, }; -use zksync_utils::bytecode::hash_bytecode; use crate::{instruction_counter::InstructionCounter, transaction::PRIVATE_KEY}; static SYSTEM_CONTRACTS: Lazy = Lazy::new(BaseSystemContracts::load_from_disk); static STORAGE: Lazy = Lazy::new(|| { - let mut storage = InMemoryStorage::with_system_contracts(hash_bytecode); + let mut storage = InMemoryStorage::with_system_contracts(); // Give `PRIVATE_KEY` some money let balance = U256::from(10u32).pow(U256::from(32)); //10^32 wei let key = storage_key_for_eth_balance(&PRIVATE_KEY.address()); diff --git a/docker/Makefile b/docker/Makefile index 4e0ca51f904e..19d5fee0907f 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -7,7 +7,7 @@ NODE_VERSION_MIN=20.17.0 YARN_VERSION_MIN=1.22.19 RUST_VERSION=nightly-2024-08-01 SQLX_CLI_VERSION=0.8.1 -FORGE_MIN_VERSION=0.2.0 +FORGE_MIN_VERSION=0.0.2 # Versions and packages checks check-nodejs: diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000000..7585238efedf --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +book diff --git a/docs/book.toml b/docs/book.toml new file mode 100644 index 000000000000..89420a95ba38 --- /dev/null +++ b/docs/book.toml @@ -0,0 +1,32 @@ +[book] +authors = ["ZKsync team"] +language = "en" +multilingual = false +src = "src" +title = "ZKsync Era Documentation" + +[output.html] +smart-punctuation = true +mathjax-support = true +git-repository-url = "https://github.com/matter-labs/zksync-era/tree/main/docs" +edit-url-template = "https://github.com/matter-labs/zksync-era/tree/main/docs/{path}" +additional-js = ["js/version-box.js", "js/mermaid-init.js"] +additional-css = ["css/version-box.css"] + +[output.html.playground] +editable = true +line-numbers = true + +[output.html.search] +limit-results = 20 +use-boolean-and = true +boost-title = 2 +boost-hierarchy = 2 +boost-paragraph = 1 +expand = true +heading-split-level = 2 + +[preprocessor] + +[preprocessor.mermaid] +command = "mdbook-mermaid" diff --git a/docs/css/version-box.css b/docs/css/version-box.css new file mode 100644 index 000000000000..4006ac7804b3 --- /dev/null +++ b/docs/css/version-box.css @@ -0,0 +1,46 @@ +#version-box { + display: flex; + align-items: center; + margin-right: 15px; /* Space from the right side */ + background-color: transparent; /* Make the box background transparent */ +} + +/* Base styles for the version selector */ +#version-selector { + background-color: transparent; /* Remove background color */ + border: 1px solid #4a5568; /* Subtle border */ + border-radius: 4px; /* Rounded edges */ + padding: 5px 10px; /* Padding inside dropdown */ + font-size: 0.9em; + font-weight: normal; + outline: none; /* Removes default focus outline */ + cursor: pointer; +} + +/* Text color for dark themes */ +.theme-navy #version-selector, +.theme-coal #version-selector { + color: #f7fafc; /* Light text color for dark backgrounds */ +} + +/* Text color for light theme */ +.theme-light #version-selector { + color: #333333; /* Dark text color for light background */ +} + +/* Hover effect for better user feedback */ +#version-selector:hover { + background-color: rgba(255, 255, 255, 0.1); /* Light hover effect */ +} + +/* Optional: Style for when the selector is focused */ +#version-selector:focus { + border-color: #63b3ed; /* Accent color for focused state */ +} + +.right-buttons { + display: flex; + flex-direction: row; /* Aligns items in a row, left to right */ + align-items: center; /* Centers items vertically */ + gap: 10px; /* Adds space between items */ +} diff --git a/docs/guides/development.md b/docs/guides/development.md deleted file mode 100644 index c859017848b5..000000000000 --- a/docs/guides/development.md +++ /dev/null @@ -1,148 +0,0 @@ -# Development guide - -This document covers development-related actions in ZKsync. - -## Initializing the project - -To setup the main toolkit, `zk`, simply run: - -``` -zk -``` - -You may also configure autocompletion for your shell via: - -``` -zk completion install -``` - -Once all the dependencies were installed, project can be initialized: - -``` -zk init -``` - -This command will do the following: - -- Generate `$ZKSYNC_HOME/etc/env/target/dev.env` file with settings for the applications. -- Initialize docker containers with `reth` Ethereum node for local development. -- Download and unpack files for cryptographical backend. -- Generate required smart contracts. -- Compile all the smart contracts. -- Deploy smart contracts to the local Ethereum network. -- Create “genesis block” for server. - -Initializing may take pretty long, but many steps (such as downloading & unpacking keys and initializing containers) are -required to be done only once. - -Usually, it is a good idea to do `zk init` once after each merge to the `main` branch (as application setup may change). - -Additionally, there is a subcommand `zk clean` to remove previously generated data. Examples: - -``` -zk clean --all # Remove generated configs, database and backups. -zk clean --config # Remove configs only. -zk clean --database # Remove database. -zk clean --backups # Remove backups. -zk clean --database --backups # Remove database *and* backups, but not configs. -``` - -**When do you need it?** - -1. If you have an initialized database and want to run `zk init`, you have to remove the database first. -2. If after getting new functionality from the `main` branch your code stopped working and `zk init` doesn't help, you - may try removing `$ZKSYNC_HOME/etc/env/target/dev.env` and running `zk init` once again. This may help if the - application configuration has changed. - -If you don’t need all of the `zk init` functionality, but just need to start/stop containers, use the following -commands: - -``` -zk up # Set up `reth` and `postgres` containers -zk down # Shut down `reth` and `postgres` containers -``` - -## Reinitializing - -When actively changing something that affects infrastructure (for example, contracts code), you normally don't need the -whole `init` functionality, as it contains many external steps (e.g. deploying ERC20 tokens) which don't have to be -redone. - -For this case, there is an additional command: - -``` -zk reinit -``` - -This command does the minimal subset of `zk init` actions required to "reinitialize" the network. It assumes that -`zk init` was called in the current environment before. If `zk reinit` doesn't work for you, you may want to run -`zk init` instead. - -## Committing changes - -`zksync` uses pre-commit and pre-push git hooks for basic code integrity checks. Hooks are set up automatically within -the workspace initialization process. These hooks will not allow to commit the code which does not pass several checks. - -Currently the following criteria are checked: - -- Rust code should always be formatted via `cargo fmt`. -- Other code should always be formatted via `zk fmt`. -- Dummy Prover should not be staged for commit (see below for the explanation). - -## Using Dummy Prover - -By default, the chosen prover is a "dummy" one, meaning that it doesn't actually compute proofs but rather uses mocks to -avoid expensive computations in the development environment. - -To switch dummy prover to real prover, one must change `dummy_verifier` to `false` in `contracts.toml` for your env -(most likely, `etc/env/base/contracts.toml`) and run `zk init` to redeploy smart contracts. - -## Testing - -- Running the `rust` unit-tests: - - ``` - zk test rust - ``` - -- Running a specific `rust` unit-test: - - ``` - zk test rust --package --lib ::tests:: - # e.g. zk test rust --package zksync_core --lib eth_sender::tests::resend_each_block - ``` - -- Running the integration test: - - ``` - zk server # Has to be run in the 1st terminal - zk test i server # Has to be run in the 2nd terminal - ``` - -- Running the benchmarks: - - ``` - zk f cargo bench - ``` - -- Running the loadtest: - - ``` - zk server # Has to be run in the 1st terminal - zk prover # Has to be run in the 2nd terminal if you want to use real prover, otherwise it's not required. - zk run loadtest # Has to be run in the 3rd terminal - ``` - -## Contracts - -### Re-build contracts - -``` -zk contract build -``` - -### Publish source code on etherscan - -``` -zk contract publish -``` diff --git a/docs/guides/external-node/docker-compose-examples/configs/mainnet_consensus_config.yaml b/docs/guides/external-node/docker-compose-examples/configs/mainnet_consensus_config.yaml deleted file mode 100644 index f2a0ce318757..000000000000 --- a/docs/guides/external-node/docker-compose-examples/configs/mainnet_consensus_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ -server_addr: '0.0.0.0:3054' -public_addr: '127.0.0.1:3054' -debug_page_addr: '0.0.0.0:5000' -max_payload_size: 5000000 -gossip_dynamic_inbound_limit: 100 -gossip_static_outbound: - # preconfigured ENs owned by Matterlabs that you can connect to - - key: 'node:public:ed25519:68d29127ab03408bf5c838553b19c32bdb3aaaae9bf293e5e078c3a0d265822a' - addr: 'external-node-consensus-mainnet.zksync.dev:3054' - - key: 'node:public:ed25519:b521e1bb173d04bc83d46b859d1296378e94a40427a6beb9e7fdd17cbd934c11' - addr: 'external-node-moby-consensus-mainnet.zksync.dev:3054' diff --git a/docs/guides/external-node/docker-compose-examples/configs/testnet_consensus_config.yaml b/docs/guides/external-node/docker-compose-examples/configs/testnet_consensus_config.yaml deleted file mode 100644 index a5f752fe405a..000000000000 --- a/docs/guides/external-node/docker-compose-examples/configs/testnet_consensus_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ -server_addr: '0.0.0.0:3054' -public_addr: '127.0.0.1:3054' -debug_page_addr: '0.0.0.0:5000' -max_payload_size: 5000000 -gossip_dynamic_inbound_limit: 100 -gossip_static_outbound: - # preconfigured ENs owned by Matterlabs that you can connect to - - key: 'node:public:ed25519:4a94067664e7b8d0927ab1443491dab71a1d0c63f861099e1852f2b6d0831c3e' - addr: 'external-node-consensus-sepolia.zksync.dev:3054' - - key: 'node:public:ed25519:cfbbebc74127099680584f07a051a2573e2dd7463abdd000d31aaa44a7985045' - addr: 'external-node-moby-consensus-sepolia.zksync.dev:3054' diff --git a/docs/guides/external-node/prepared_configs/mainnet_consensus_config.yaml b/docs/guides/external-node/prepared_configs/mainnet_consensus_config.yaml deleted file mode 100644 index be37aaf29329..000000000000 --- a/docs/guides/external-node/prepared_configs/mainnet_consensus_config.yaml +++ /dev/null @@ -1,14 +0,0 @@ -server_addr: '0.0.0.0:3054' -public_addr: ':3054' -max_payload_size: 5000000 -gossip_dynamic_inbound_limit: 100 -gossip_static_outbound: - # preconfigured ENs owned by Matterlabs that you can connect to - - key: 'node:public:ed25519:68d29127ab03408bf5c838553b19c32bdb3aaaae9bf293e5e078c3a0d265822a' - addr: 'external-node-consensus-mainnet.zksync.dev:3054' - - key: 'node:public:ed25519:b521e1bb173d04bc83d46b859d1296378e94a40427a6beb9e7fdd17cbd934c11' - addr: 'external-node-moby-consensus-mainnet.zksync.dev:3054' - - key: 'node:public:ed25519:45d23515008b5121484eb774507df63ff4ce9f4b65e6a03b7c9ec4e0474d3044' - addr: 'consensus-mainnet-1.zksync-nodes.com:3054' - - key: 'node:public:ed25519:c278bb0831e8d0dcd3aaf0b7af7c3dca048d50b28c578ceecce61a412986b883' - addr: 'consensus-mainnet-2.zksync-nodes.com:3054' diff --git a/docs/guides/external-node/prepared_configs/testnet_consensus_config.yaml b/docs/guides/external-node/prepared_configs/testnet_consensus_config.yaml deleted file mode 100644 index 8d2551c07087..000000000000 --- a/docs/guides/external-node/prepared_configs/testnet_consensus_config.yaml +++ /dev/null @@ -1,14 +0,0 @@ -server_addr: '0.0.0.0:3054' -public_addr: ':3054' -max_payload_size: 5000000 -gossip_dynamic_inbound_limit: 100 -gossip_static_outbound: - # preconfigured ENs owned by Matterlabs that you can connect to - - key: 'node:public:ed25519:4a94067664e7b8d0927ab1443491dab71a1d0c63f861099e1852f2b6d0831c3e' - addr: 'external-node-consensus-sepolia.zksync.dev:3054' - - key: 'node:public:ed25519:cfbbebc74127099680584f07a051a2573e2dd7463abdd000d31aaa44a7985045' - addr: 'external-node-moby-consensus-sepolia.zksync.dev:3054' - - key: 'node:public:ed25519:f48616db5965ada49dcbd51b1de11068a27c9886c900d3522607f16dff2e66fc' - addr: 'consensus-sepolia-1.zksync-nodes.com:3054' - - key: 'node:public:ed25519:3789d49293792755a9c1c2a7ed9b0e210e92994606dcf76388b5635d7ed676cb' - addr: 'consensus-sepolia-2.zksync-nodes.com:3054' diff --git a/docs/guides/launch.md b/docs/guides/launch.md deleted file mode 100644 index 10c0b10f5d84..000000000000 --- a/docs/guides/launch.md +++ /dev/null @@ -1,343 +0,0 @@ -# Running the application - -This document covers common scenarios for launching ZKsync applications set locally. - -## Prerequisites - -Prepare dev environment prerequisites: see - -[Installing dependencies](./setup-dev.md) - -## Setup local dev environment - -Setup: - -``` -zk # installs and builds zk itself -zk init -``` - -If you face any other problems with the `zk init` command, go to the -[Troubleshooting](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/launch.md#troubleshooting) section at -the end of this file. There are solutions for some common error cases. - -To completely reset the dev environment: - -- Stop services: - - ``` - zk down - ``` - -- Repeat the setup procedure above - -If `zk init` has already been executed, and now you only need to start docker containers (e.g. after reboot), simply -launch: - -``` -zk up -``` - -### Run observability stack - -If you want to run [Dockprom](https://github.com/stefanprodan/dockprom/) stack (Prometheus, Grafana) alongside other -containers - add `--run-observability` parameter during initialisation. - -``` -zk init --run-observability -``` - -That will also provision Grafana with -[era-observability](https://github.com/matter-labs/era-observability/tree/main/dashboards) dashboards. You can then -access it at `http://127.0.0.1:3000/` under credentials `admin/admin`. - -> If you don't see any data displayed on the Grafana dashboards - try setting the timeframe to "Last 30 minutes". You -> will also have to have `jq` installed on your system. - -## (Re)deploy db and contracts - -``` -zk contract redeploy -``` - -## Environment configurations - -Env config files are held in `etc/env/target/` - -List configurations: - -``` -zk env -``` - -Switch between configurations: - -``` -zk env -``` - -Default configuration is `dev.env`, which is generated automatically from `dev.env.example` during `zk init` command -execution. - -## Build and run server - -Run server: - -``` -zk server -``` - -Server is configured using env files in `./etc/env` directory. After the first initialization, file -`./etc/env/target/dev.env`will be created. By default, this file is copied from the `./etc/env/target/dev.env.example` -template. - -Make sure you have environment variables set right, you can check it by running: `zk env`. You should see `* dev` in -output. - -## Running server using Google cloud storage object store instead of default In memory store - -Get the service_account.json file containing the GCP credentials from kubernetes secret for relevant environment(stage2/ -testnet2) add that file to the default location ~/gcloud/service_account.json or update object_store.toml with the file -location - -``` -zk server -``` - -## Running prover server - -Running on machine without GPU - -```shell -zk f cargo +nightly run --release --bin zksync_prover -``` - -Running on machine with GPU - -```shell -zk f cargo +nightly run --features gpu --release --bin zksync_prover -``` - -## Running the verification key generator - -```shell -# ensure that the setup_2^26.key in the current directory, the file can be download from https://storage.googleapis.com/matterlabs-setup-keys-us/setup-keys/setup_2\^26.key - -# To generate all verification keys -cargo run --release --bin zksync_verification_key_generator - - -``` - -## Generating binary verification keys for existing json verification keys - -```shell -cargo run --release --bin zksync_json_to_binary_vk_converter -- -o /path/to/output-binary-vk -``` - -## Generating commitment for existing verification keys - -```shell -cargo run --release --bin zksync_commitment_generator -``` - -## Running the contract verifier - -```shell -# To process fixed number of jobs -cargo run --release --bin zksync_contract_verifier -- --jobs-number X - -# To run until manual exit -zk contract_verifier -``` - -## Troubleshooting - -### SSL error: certificate verify failed - -**Problem**. `zk init` fails with the following error: - -``` -Initializing download: https://storage.googleapis.com/matterlabs-setup-keys-us/setup-keys/setup_2%5E20.key -SSL error: certificate verify failed -``` - -**Solution**. Make sure that the version of `axel` on your computer is `2.17.10` or higher. - -### rmSync is not a function - -**Problem**. `zk init` fails with the following error: - -``` -fs_1.default.rmSync is not a function -``` - -**Solution**. Make sure that the version of `node.js` installed on your computer is `14.14.0` or higher. - -### Invalid bytecode: () - -**Problem**. `zk init` fails with an error similar to: - -``` -Running `target/release/zksync_server --genesis` -2023-04-05T14:23:40.291277Z INFO zksync_core::genesis: running regenesis -thread 'main' panicked at 'Invalid bytecode: ()', core/lib/utils/src/bytecode.rs:159:10 -stack backtrace: - 0: 0x104551410 - std::backtrace_rs::backtrace::libunwind::trace::hf9c5171f212b04e2 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5 - 1: 0x104551410 - std::backtrace_rs::backtrace::trace_unsynchronized::h179003f6ec753118 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5 - 2: 0x104551410 - std::sys_common::backtrace::_print_fmt::h92d38f701cf42b17 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/sys_common/backtrace.rs:65:5 - 3: 0x104551410 - ::fmt::hb33e6e8152f78c95 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/sys_common/backtrace.rs:44:22 - 4: 0x10456cdb0 - core::fmt::write::hd33da007f7a27e39 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/fmt/mod.rs:1208:17 - 5: 0x10454b41c - std::io::Write::write_fmt::h7edc10723862001e - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/io/mod.rs:1682:15 - 6: 0x104551224 - std::sys_common::backtrace::_print::h5e00f05f436af01f - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/sys_common/backtrace.rs:47:5 - 7: 0x104551224 - std::sys_common::backtrace::print::h895ee35b3f17b334 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/sys_common/backtrace.rs:34:9 - 8: 0x104552d84 - std::panicking::default_hook::{{closure}}::h3b7ee083edc2ea3e - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:267:22 - 9: 0x104552adc - std::panicking::default_hook::h4e7c2c28eba716f5 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:286:9 - 10: 0x1045533a8 - std::panicking::rust_panic_with_hook::h1672176227032c45 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:688:13 - 11: 0x1045531c8 - std::panicking::begin_panic_handler::{{closure}}::h0b2d072f9624d32e - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:579:13 - 12: 0x104551878 - std::sys_common::backtrace::__rust_end_short_backtrace::he9abda779115b93c - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/sys_common/backtrace.rs:137:18 - 13: 0x104552f24 - rust_begin_unwind - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:575:5 - 14: 0x1045f89c0 - core::panicking::panic_fmt::h23ae44661fec0889 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/panicking.rs:64:14 - 15: 0x1045f8ce0 - core::result::unwrap_failed::h414a6cbb12b1e143 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/result.rs:1791:5 - 16: 0x103f79a30 - zksync_utils::bytecode::hash_bytecode::h397dd7c5b6202bf4 - 17: 0x103e47e78 - zksync_contracts::BaseSystemContracts::load_from_disk::h0e2da8f63292ac46 - 18: 0x102d885a0 - zksync_core::genesis::ensure_genesis_state::{{closure}}::h5143873f2c337e11 - 19: 0x102d7dee0 - zksync_core::genesis_init::{{closure}}::h4e94f3d4ad984788 - 20: 0x102d9c048 - zksync_server::main::{{closure}}::h3fe943a3627d31e1 - 21: 0x102d966f8 - tokio::runtime::park::CachedParkThread::block_on::h2f2fdf7edaf08470 - 22: 0x102df0dd4 - tokio::runtime::runtime::Runtime::block_on::h1fd1d83272a23194 - 23: 0x102e21470 - zksync_server::main::h500621fd4d160768 - 24: 0x102d328f0 - std::sys_common::backtrace::__rust_begin_short_backtrace::h52973e519e2e8a0d - 25: 0x102e08ea8 - std::rt::lang_start::{{closure}}::hbd395afe0ab3b799 - 26: 0x10454508c - core::ops::function::impls:: for &F>::call_once::ha1c2447b9b665e13 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/ops/function.rs:606:13 - 27: 0x10454508c - std::panicking::try::do_call::ha57d6d1e9532dc1f - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:483:40 - 28: 0x10454508c - std::panicking::try::hca0526f287961ecd - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:447:19 - 29: 0x10454508c - std::panic::catch_unwind::hdcaa7fa896e0496a - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panic.rs:137:14 - 30: 0x10454508c - std::rt::lang_start_internal::{{closure}}::h142ec071d3766871 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/rt.rs:148:48 - 31: 0x10454508c - std::panicking::try::do_call::h95f5e55d6f048978 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:483:40 - 32: 0x10454508c - std::panicking::try::h0fa00e2f7b4a5c64 - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:447:19 - 33: 0x10454508c - std::panic::catch_unwind::h1765f149814d4d3e - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panic.rs:137:14 - 34: 0x10454508c - std::rt::lang_start_internal::h00a235e820a7f01c - at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/rt.rs:148:20 - 35: 0x102e21578 - _main -Error: Genesis is not needed (either Postgres DB or tree's Rocks DB is not empty) -``` - -**Description**. This means that your bytecode config file has an empty entry: `"bytecode": "0x"`. This happens because -your `zksync-2-dev/etc/system-contracts/package.json`'s dependency on `"@matterlabs/hardhat-zksync-solc"` is outdated. -We don't expect this error to happen as we've updated to latest version which fixes the problem. - -**Solution**. Update your dependency and reinit: - -``` -yarn add -D @matterlabs/hardhat-zksync-solc # in the system-contracts folder -zk clean --all && zk init -``` - -On the run, it moved from: - -``` - "@matterlabs/hardhat-zksync-solc": "^0.3.14-beta.3", -``` - -to: - -``` - "@matterlabs/hardhat-zksync-solc": "^0.3.15", -``` - -### Error: Bytecode length in 32-byte words must be odd - -**Problem**. `zk init` fails with an error similar to: - -``` -Successfully generated Typechain artifacts! -Error: Error: Bytecode length in 32-byte words must be odd - at hashL2Bytecode (/Users/emilluta/code/zksync-2-dev/contracts/zksync/src/utils.ts:29:15) - at computeL2Create2Address (/Users/emilluta/code/zksync-2-dev/contracts/zksync/src/utils.ts:53:26) - at /Users/emilluta/code/zksync-2-dev/contracts/zksync/src/compileAndDeployLibs.ts:50:63 - at step (/Users/emilluta/code/zksync-2-dev/contracts/zksync/src/compileAndDeployLibs.ts:33:23) - at Object.next (/Users/emilluta/code/zksync-2-dev/contracts/zksync/src/compileAndDeployLibs.ts:14:53) - at fulfilled (/Users/emilluta/code/zksync-2-dev/contracts/zksync/src/compileAndDeployLibs.ts:5:58) -error Command failed with exit code 1. -info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. -error Command failed. -Exit code: 1 -Command: /Users/emilluta/.nvm/versions/node/v16.19.1/bin/node -Arguments: /opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js compile-and-deploy-libs -Directory: /Users/emilluta/code/zksync-2-dev/contracts/zksync -Output: - -info Visit https://yarnpkg.com/en/docs/cli/workspace for documentation about this command. -error Command failed with exit code 1. -info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. -Error: Child process exited with code 1 -``` - -**Description**. This means that your bytecode config file has an empty entry: `"bytecode": "0x"`. This happens because -your `zksync-2-dev/contracts/zksync/package.json`'s dependency on `"@matterlabs/hardhat-zksync-solc"` is outdated. We -don't expect this error to happen as we've updated to latest version which fixes the problem. - -**Solution**. Update your dependency and reinit: - -``` -yarn add -D @matterlabs/hardhat-zksync-solc # in the system-contracts folder -zk clean --all && zk init -``` - -On the run, it moved from: - -``` - "@matterlabs/hardhat-zksync-solc": "^0.3.14-beta.3", -``` - -to: - -``` - "@matterlabs/hardhat-zksync-solc": "^0.3.15", -``` - -### Error: Cannot read properties of undefined (reading 'compilerPath') - -**Problem**. `zk init` fails with an error similar to the following: - -```text -Yarn project directory: /Users//Projects/zksync-era/contracts/system-contracts -Error: Cannot read properties of undefined (reading 'compilerPath') -error Command failed with exit code 1. -``` - -**Description**. The compiler downloader -[could not verify](https://github.com/NomicFoundation/hardhat/blob/0d850d021f3ab33b59b1ea2ae70d1e659e579e40/packages/hardhat-core/src/internal/solidity/compiler/downloader.ts#L336-L383) -that the Solidity compiler it downloaded actually works. - -**Solution**. Delete the cached `*.does.not.work` file to run the check again: - -```sh -# NOTE: Compiler version, commit hash may differ. -rm $HOME/Library/Caches/hardhat-nodejs/compilers-v2/macosx-amd64/solc-macosx-amd64-v0.8.20+commit.a1b79de6.does.not.work -``` diff --git a/docs/js/mermaid-init.js b/docs/js/mermaid-init.js new file mode 100644 index 000000000000..15a7f4e57c60 --- /dev/null +++ b/docs/js/mermaid-init.js @@ -0,0 +1,35 @@ +(() => { + const darkThemes = ['ayu', 'navy', 'coal']; + const lightThemes = ['light', 'rust']; + + const classList = document.getElementsByTagName('html')[0].classList; + + let lastThemeWasLight = true; + for (const cssClass of classList) { + if (darkThemes.includes(cssClass)) { + lastThemeWasLight = false; + break; + } + } + + const theme = lastThemeWasLight ? 'default' : 'dark'; + mermaid.initialize({ startOnLoad: true, theme }); + + // Simplest way to make mermaid re-render the diagrams in the new theme is via refreshing the page + + for (const darkTheme of darkThemes) { + document.getElementById(darkTheme).addEventListener('click', () => { + if (lastThemeWasLight) { + window.location.reload(); + } + }); + } + + for (const lightTheme of lightThemes) { + document.getElementById(lightTheme).addEventListener('click', () => { + if (!lastThemeWasLight) { + window.location.reload(); + } + }); + } +})(); diff --git a/docs/js/version-box.js b/docs/js/version-box.js new file mode 100644 index 000000000000..932a75a5e3bb --- /dev/null +++ b/docs/js/version-box.js @@ -0,0 +1,61 @@ +document.addEventListener('DOMContentLoaded', function () { + // Get the base URL from the mdBook configuration + const baseUrl = document.location.origin + '/zksync-era/core'; + + // Function to create version selector + function createVersionSelector(versions) { + const versionSelector = document.createElement('select'); + versionSelector.id = 'version-selector'; + + // Get the current path + const currentPath = window.location.pathname; + + // Iterate over the versions object + for (const [versionName, versionUrl] of Object.entries(versions)) { + const option = document.createElement('option'); + option.value = versionUrl + '/'; + option.textContent = versionName; + + // Check if the current URL matches this option's value + if (currentPath.includes(option.value)) { + option.selected = true; // Set this option as selected + } + + versionSelector.appendChild(option); + } + + // Event listener to handle version change + versionSelector.addEventListener('change', function () { + const selectedVersion = versionSelector.value; + // Redirect to the selected version URL + window.location.href = '/zksync-era/core' + selectedVersion; + }); + + return versionSelector; + } + + // Fetch versions from JSON file + fetch(baseUrl + '/versions.json') + .then((response) => { + if (!response.ok) { + throw new Error('Network response was not ok ' + response.statusText); + } + return response.json(); + }) + .then((data) => { + const versionSelector = createVersionSelector(data); + const nav = document.querySelector('.right-buttons'); + + if (nav) { + const versionBox = document.createElement('div'); + versionBox.id = 'version-box'; + versionBox.appendChild(versionSelector); + nav.appendChild(versionBox); // Append to the .right-buttons container + } else { + console.error('.right-buttons element not found.'); + } + }) + .catch((error) => { + console.error('There has been a problem with your fetch operation:', error); + }); +}); diff --git a/docs/src/README.md b/docs/src/README.md new file mode 100644 index 000000000000..ab6a417877b5 --- /dev/null +++ b/docs/src/README.md @@ -0,0 +1,26 @@ +# Introduction + +Welcome to the documentation! This guide provides comprehensive insights into the architecture, setup, usage, and +advanced features of ZKsync. + +## Documentation Structure + +- **Guides**: The Guides section is designed to help users at every level, from setup and development to advanced + configuration and debugging techniques. It covers essential topics, including Docker setup, repository management, and + architecture. + +- **Specs**: This section dives into the technical specifications of our system. Here, you’ll find detailed + documentation on data availability, L1 and L2 communication, smart contract interactions, Zero-Knowledge proofs, and + more. Each topic includes an in-depth explanation to support advanced users and developers. + +- **Announcements**: This section highlights important updates, announcements, and committee details, providing + essential information to keep users informed on the latest changes. + +## Getting Started + +Feel free to explore each section according to your needs. This documentation is designed to be modular, so you can jump +to specific topics or follow through step-by-step. + +--- + +Thank you for using our documentation! diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md new file mode 100644 index 000000000000..c267759cb4c6 --- /dev/null +++ b/docs/src/SUMMARY.md @@ -0,0 +1,86 @@ + + +# Summary + +[Introduction](README.md) + +# Guides + +- [Basic](guides/README.md) + + - [Architecture](guides/architecture.md) + - [Build Docker](guides/build-docker.md) + - [Development](guides/development.md) + - [Launch](guides/launch.md) + - [Repositories](guides/repositories.md) + - [Setup Dev](guides/setup-dev.md) + +- [Advanced](guides/advanced/README.md) + - [Local initialization](guides/advanced/01_initialization.md) + - [Deposits](guides/advanced/02_deposits.md) + - [Withdrawals](guides/advanced/03_withdrawals.md) + - [Contracts](guides/advanced/04_contracts.md) + - [Calls](guides/advanced/05_how_call_works.md) + - [Transactions](guides/advanced/06_how_transaction_works.md) + - [Fee Model](guides/advanced/07_fee_model.md) + - [L2 Messaging](guides/advanced/08_how_l2_messaging_works.md) + - [Pubdata](guides/advanced/09_pubdata.md) + - [Pubdata with Blobs](guides/advanced/10_pubdata_with_blobs.md) + - [Bytecode compression](guides/advanced/11_compression.md) + - [EraVM intro](guides/advanced/12_alternative_vm_intro.md) + - [ZK Intuition](guides/advanced/13_zk_intuition.md) + - [ZK Deeper Dive](guides/advanced/14_zk_deeper_overview.md) + - [Prover Keys](guides/advanced/15_prover_keys.md) + - [Advanced Debugging](guides/advanced/90_advanced_debugging.md) + - [Docker and CI](guides/advanced/91_docker_and_ci.md) + +# External Node + +- [External node](guides/external-node/01_intro.md) + - [Quick Start](guides/external-node/00_quick_start.md) + - [Configuration](guides/external-node/02_configuration.md) + - [Running](guides/external-node/03_running.md) + - [Observability](guides/external-node/04_observability.md) + - [Troubleshooting](guides/external-node/05_troubleshooting.md) + - [Components](guides/external-node/06_components.md) + - [Snapshots Recovery](guides/external-node/07_snapshots_recovery.md) + - [Pruning](guides/external-node/08_pruning.md) + - [Treeless Mode](guides/external-node/09_treeless_mode.md) + - [Decentralization](guides/external-node/10_decentralization.md) + +# Specs + +- [Introduction](specs/introduction.md) + - [Overview](specs/overview.md) + - [Blocks and Batches](specs/blocks_batches.md) + - [L1 Smart Contracts](specs/l1_smart_contracts.md) +- [Data Availability](specs/data_availability/overview.md) + - [Pubdata](specs/data_availability/pubdata.md) + - [Compression](specs/data_availability/compression.md) + - [Reconstruction](specs/data_availability/reconstruction.md) + - [Validium ZK Porter](specs/data_availability/validium_zk_porter.md) +- [L1 L2 Communication](specs/l1_l2_communication/overview_deposits_withdrawals.md) + - [L1 to L2](specs/l1_l2_communication/l1_to_l2.md) + - [L2 to L1](specs/l1_l2_communication/l2_to_l1.md) +- [Prover](specs/prover/overview.md) + - [Getting Started](specs/prover/getting_started.md) + - [ZK Terminology](specs/prover/zk_terminology.md) + - [Function Check if Satisfied](specs/prover/boojum_function_check_if_satisfied.md) + - [Gadgets](specs/prover/boojum_gadgets.md) + - [Circuit Testing](specs/prover/circuit_testing.md) + - [Circuits Overview](specs/prover/circuits/overview.md) +- [ZK Chains](specs/zk_chains/overview.md) + - [Gateway](specs/zk_chains/gateway.md) + - [Interop](specs/zk_chains/interop.md) + - [Shared Bridge](specs/zk_chains/shared_bridge.md) +- [ZK EVM](specs/zk_evm/vm_overview.md) + - [Account Abstraction](specs/zk_evm/account_abstraction.md) + - [Bootloader](specs/zk_evm/bootloader.md) + - [Fee Model](specs/zk_evm/fee_model.md) + - [Precompiles](specs/zk_evm/precompiles.md) + - [System Contracts](specs/zk_evm/system_contracts.md) + +# Announcements + +- [Announcements](announcements/README.md) + - [Attester Committee](announcements/attester_commitee.md) diff --git a/docs/announcements/README.md b/docs/src/announcements/README.md similarity index 100% rename from docs/announcements/README.md rename to docs/src/announcements/README.md diff --git a/docs/announcements/attester_commitee.md b/docs/src/announcements/attester_commitee.md similarity index 97% rename from docs/announcements/attester_commitee.md rename to docs/src/announcements/attester_commitee.md index 84ff8aa5be6d..148e51a4f976 100644 --- a/docs/announcements/attester_commitee.md +++ b/docs/src/announcements/attester_commitee.md @@ -36,7 +36,7 @@ Participants can leave the committee at any time. The only action that is required to participate is to share your attester public key with the Main Node operator (by opening an issue in this repo or using any other communication channel). You can find it in the comment in the `consensus_secrets.yaml` file (that was - in most cases - generated by the tool described -[here](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/09_decentralization.md#generating-secrets)) +[here](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/10_decentralization.md#generating-secrets)) > [!WARNING] > diff --git a/docs/src/guides/README.md b/docs/src/guides/README.md new file mode 100644 index 000000000000..f9d5bc852a26 --- /dev/null +++ b/docs/src/guides/README.md @@ -0,0 +1,12 @@ +# ZKsync basic guides + +This section contains basic guides that aim to explain the ZKsync ecosystem in an easy to grasp way. + +## Table of Contents + +- [Architecture](./architecture.md) +- [Build Docker](./build-docker.md) +- [Development](./development.md) +- [Launch](./launch.md) +- [Repositories](./repositories.md) +- [Setup Dev](./setup-dev.md) diff --git a/docs/guides/advanced/01_initialization.md b/docs/src/guides/advanced/01_initialization.md similarity index 75% rename from docs/guides/advanced/01_initialization.md rename to docs/src/guides/advanced/01_initialization.md index 79c33434d3b5..2bc4a9c3a459 100644 --- a/docs/guides/advanced/01_initialization.md +++ b/docs/src/guides/advanced/01_initialization.md @@ -1,4 +1,4 @@ -# ZKsync deeper dive +# ZKsync Deeper Dive The goal of this doc is to show you some more details on how ZKsync works internally. @@ -7,18 +7,22 @@ system). Now let's take a look at what's inside: -### Initialization (zk init) +### Initialization -Let's take a deeper look into what `zk init` does. +Let's take a deeper look into what `zkstack ecosystem init` does. -#### zk tool +#### ZK Stack CLI -`zk` itself is implemented in typescript (you can see the code in `infrastructure` directory). If you change anything -there, make sure to run `zk` (that compiles this code), before re-running `zk init`. +`zkstack` itself is implemented in Rust (you can see the code in `/zkstack_cli` directory). If you change anything +there, make sure to run `zkstackup --local` from the root folder (that compiles and installs this code), before +re-running any `zkstack` command. -#### zk init +#### Containers -As first step, it gets the docker images for postgres and reth. +The first step to initialize a ZK Stack ecosystem is to run the command `zkstack containers`. This command gets the +docker images for `postgres` and `reth`. If the `--observability` option is passed to the command, or the corresponding +option is selected in the interactive prompt, then Prometheus, Grafana and other observability-related images are +downloaded and run. Reth (one of the Ethereum clients) will be used to setup our own copy of L1 chain (that our local ZKsync would use). @@ -26,11 +30,19 @@ Postgres is one of the two databases, that is used by ZKsync (the other one is R stored in postgres (blocks, transactions etc) - while RocksDB is only storing the state (Tree & Map) - and it used by VM. -Then we compile JS packages (these include our web3 sdk, tools and testing infrastructure). +#### Ecosystem -Then L1 & L2 contracts. +The next step is to run the command `zkstack ecosystem init`. -And now we're ready to start setting up the system. +This command: + +- Collects and finalize the ecosystem configuration. +- Builds and deploys L1 & L2 contracts. +- Initializes each chain defined in the `/chains` folder. (Currently, a single chain `era` is defined there, but you can + create your own chains running `zkstack chain create`). +- Sets up observability. +- Runs the genesis process. +- Initializes the database. #### Postgres @@ -83,8 +95,8 @@ If everything goes well, you should see that L1 blocks are being produced. Now we can start the main server: -```shell -zk server +```bash +zkstack server ``` This will actually run a cargo binary (`zksync_server`). @@ -96,7 +108,7 @@ Currently we don't send any transactions there (so the logs might be empty). But you should see some initial blocks in postgres: -``` +```sql select * from miniblocks; ``` @@ -107,7 +119,7 @@ Let's finish this article, by taking a look at our L1: We will use the `web3` tool to communicate with the L1, have a look at [02_deposits.md](02_deposits.md) for installation instructions. You can check that you're a (localnet) crypto trillionaire, by running: -```shell +```bash ./web3 --rpc-url http://localhost:8545 balance 0x36615Cf349d7F6344891B1e7CA7C72883F5dc049 ``` @@ -120,14 +132,14 @@ In order to communicate with L2 (our ZKsync) - we have to deploy multiple contra Ethereum). You can look on the `deployL1.log` file - to see the list of contracts that were deployed and their accounts. First thing in the file, is the deployer/governor wallet - this is the account that can change, freeze and unfreeze the -contracts (basically the owner). You can also verify (using the getBalance method above), that is has a lot of tokens. +contracts (basically the owner). You can verify the token balance using the `getBalance` method above. Then, there are a bunch of contracts (CRATE2_FACTOR, DIAMOND_PROXY, L1_ALLOW_LIST etc etc) - for each one, the file contains the address. You can quickly verify that they were really deployed, by calling: -```shell +```bash ./web3 --rpc-url http://localhost:8545 address XXX ``` diff --git a/docs/guides/advanced/02_deposits.md b/docs/src/guides/advanced/02_deposits.md similarity index 100% rename from docs/guides/advanced/02_deposits.md rename to docs/src/guides/advanced/02_deposits.md diff --git a/docs/guides/advanced/03_withdrawals.md b/docs/src/guides/advanced/03_withdrawals.md similarity index 100% rename from docs/guides/advanced/03_withdrawals.md rename to docs/src/guides/advanced/03_withdrawals.md diff --git a/docs/guides/advanced/04_contracts.md b/docs/src/guides/advanced/04_contracts.md similarity index 100% rename from docs/guides/advanced/04_contracts.md rename to docs/src/guides/advanced/04_contracts.md diff --git a/docs/guides/advanced/05_how_call_works.md b/docs/src/guides/advanced/05_how_call_works.md similarity index 98% rename from docs/guides/advanced/05_how_call_works.md rename to docs/src/guides/advanced/05_how_call_works.md index 5b9458ddce8e..0126c5349e90 100644 --- a/docs/guides/advanced/05_how_call_works.md +++ b/docs/src/guides/advanced/05_how_call_works.md @@ -12,7 +12,7 @@ Since the 'call' method is only for reading data, all the calculations will happ ### Calling the 'call' method If you need to make calls quickly, you can use the 'cast' binary from the -[foundry](https://github.com/foundry-rs/foundry) suite: +[Foundry ZKsync](https://foundry-book.zksync.io/getting-started/installation) suite: ```shell= cast call 0x23DF7589897C2C9cBa1C3282be2ee6a938138f10 "myfunction()()" --rpc-url http://localhost:3050 diff --git a/docs/guides/advanced/06_how_transaction_works.md b/docs/src/guides/advanced/06_how_transaction_works.md similarity index 100% rename from docs/guides/advanced/06_how_transaction_works.md rename to docs/src/guides/advanced/06_how_transaction_works.md diff --git a/docs/guides/advanced/07_fee_model.md b/docs/src/guides/advanced/07_fee_model.md similarity index 100% rename from docs/guides/advanced/07_fee_model.md rename to docs/src/guides/advanced/07_fee_model.md diff --git a/docs/guides/advanced/08_how_l2_messaging_works.md b/docs/src/guides/advanced/08_how_l2_messaging_works.md similarity index 100% rename from docs/guides/advanced/08_how_l2_messaging_works.md rename to docs/src/guides/advanced/08_how_l2_messaging_works.md diff --git a/docs/guides/advanced/09_pubdata.md b/docs/src/guides/advanced/09_pubdata.md similarity index 100% rename from docs/guides/advanced/09_pubdata.md rename to docs/src/guides/advanced/09_pubdata.md diff --git a/docs/guides/advanced/10_pubdata_with_blobs.md b/docs/src/guides/advanced/10_pubdata_with_blobs.md similarity index 100% rename from docs/guides/advanced/10_pubdata_with_blobs.md rename to docs/src/guides/advanced/10_pubdata_with_blobs.md diff --git a/docs/guides/advanced/11_compression.md b/docs/src/guides/advanced/11_compression.md similarity index 100% rename from docs/guides/advanced/11_compression.md rename to docs/src/guides/advanced/11_compression.md diff --git a/docs/guides/advanced/12_alternative_vm_intro.md b/docs/src/guides/advanced/12_alternative_vm_intro.md similarity index 100% rename from docs/guides/advanced/12_alternative_vm_intro.md rename to docs/src/guides/advanced/12_alternative_vm_intro.md diff --git a/docs/guides/advanced/13_zk_intuition.md b/docs/src/guides/advanced/13_zk_intuition.md similarity index 100% rename from docs/guides/advanced/13_zk_intuition.md rename to docs/src/guides/advanced/13_zk_intuition.md diff --git a/docs/guides/advanced/14_zk_deeper_overview.md b/docs/src/guides/advanced/14_zk_deeper_overview.md similarity index 100% rename from docs/guides/advanced/14_zk_deeper_overview.md rename to docs/src/guides/advanced/14_zk_deeper_overview.md diff --git a/docs/guides/advanced/15_prover_keys.md b/docs/src/guides/advanced/15_prover_keys.md similarity index 100% rename from docs/guides/advanced/15_prover_keys.md rename to docs/src/guides/advanced/15_prover_keys.md diff --git a/docs/guides/advanced/90_advanced_debugging.md b/docs/src/guides/advanced/90_advanced_debugging.md similarity index 100% rename from docs/guides/advanced/90_advanced_debugging.md rename to docs/src/guides/advanced/90_advanced_debugging.md diff --git a/docs/guides/advanced/91_docker_and_ci.md b/docs/src/guides/advanced/91_docker_and_ci.md similarity index 93% rename from docs/guides/advanced/91_docker_and_ci.md rename to docs/src/guides/advanced/91_docker_and_ci.md index ff1c7843b8b1..885d3155dd6c 100644 --- a/docs/guides/advanced/91_docker_and_ci.md +++ b/docs/src/guides/advanced/91_docker_and_ci.md @@ -64,8 +64,8 @@ zk After this, you can run any commands you need. -When you see a command like `ci_run zk contract build` in the CI - this simply means that it executed -`zk contract build` inside that docker container. +When you see a command like `ci_run zkstack dev contracts` in the CI - this simply means that it executed +`zkstack dev contracts` inside that docker container. **IMPORTANT** - by default, docker is running in the mode, where it does NOT persist the changes. So if you exit that shell, all the changes will be removed (so when you restart, you'll end up in the same pristine condition). You can diff --git a/docs/guides/advanced/README.md b/docs/src/guides/advanced/README.md similarity index 98% rename from docs/guides/advanced/README.md rename to docs/src/guides/advanced/README.md index 5a3673b558ad..48555ed0d9c9 100644 --- a/docs/guides/advanced/README.md +++ b/docs/src/guides/advanced/README.md @@ -22,7 +22,7 @@ way. - [Prover keys](./15_prover_keys.md) Additionally, there are a few articles that cover specific topics that may be useful for developers actively working on -`zksync-era` repo. +`zksync-era` repo: - [Advanced debugging](./90_advanced_debugging.md) - [Docker and CI](./91_docker_and_ci.md) diff --git a/docs/guides/architecture.md b/docs/src/guides/architecture.md similarity index 100% rename from docs/guides/architecture.md rename to docs/src/guides/architecture.md diff --git a/docs/guides/build-docker.md b/docs/src/guides/build-docker.md similarity index 100% rename from docs/guides/build-docker.md rename to docs/src/guides/build-docker.md diff --git a/docs/src/guides/development.md b/docs/src/guides/development.md new file mode 100644 index 000000000000..fb8dd44a6c7a --- /dev/null +++ b/docs/src/guides/development.md @@ -0,0 +1,197 @@ +# Development guide + +This document outlines the steps for setting up and working with ZKsync. + +## Prerequisites + +If you haven't already, install the prerequisites as described in [Install Dependencies](./setup-dev.md). + +## Installing the local ZK Stack CLI + +To set up local development, begin by installing +[ZK Stack CLI](https://github.com/matter-labs/zksync-era/blob/main/zkstack_cli/README.md). From the project's root +directory, run the following commands: + +```bash +cd ./zkstack_cli/zkstackup +./install --local +``` + +This installs `zkstackup` in your user binaries directory (e.g., `$HOME/.local/bin/`) and adds it to your `PATH`. + +After installation, open a new terminal or reload your shell profile. From the project's root directory, you can now +run: + +```bash +zkstackup --local +``` + +This command installs `zkstack` from the current source directory. + +You can proceed to verify the installation and start familiarizing with the CLI by running: + +```bash +zkstack --help +``` + +> NOTE: Whenever you want to update you local installation with your changes, just rerun: +> +> ```bash +> zkstackup --local +> ``` +> +> You might find convenient to add this alias to your shell profile: +> +> `alias zkstackup='zkstackup --path /path/to/zksync-era'` + +## Configure Ecosystem + +The project root directory includes configuration files for an ecosystem with a single chain, `era`. To initialize the +ecosystem, first start the required containers: + +```bash +zkstack containers +``` + +Next, run: + +```bash +zkstack ecosystem init +``` + +These commands will guide you through the configuration options for setting up the ecosystem. + +> NOTE: For local development only. You can also use the development defaults by supplying the `--dev` flag. + +Initialization may take some time, but key steps (such as downloading and unpacking keys or setting up containers) only +need to be completed once. + +To see more detailed output, you can run commands with the `--verbose` flag. + +## Cleanup + +To clean up the local ecosystem (e.g., removing containers and clearing the contract cache), run: + +```bash +zkstack dev clean all +``` + +You can then reinitialize the ecosystem as described in the [Configure Ecosystem](#configure-ecosystem) section. + +```bash +zkstack containers +zkstack ecosystem init +``` + +## Committing changes + +`zksync` uses pre-commit and pre-push git hooks for basic code integrity checks. Hooks are set up automatically within +the workspace initialization process. These hooks will not allow to commit the code which does not pass several checks. + +Currently the following criteria are checked: + +- Code must be formatted via `zkstack dev fmt`. +- Code must be linted via `zkstack dev lint`. + +## Testing + +ZKstack CLI offers multiple subcommands to run specific integration and unit test: + +```bash +zkstack dev test --help +``` + +```bash +Usage: zkstack dev test [OPTIONS] + +Commands: + integration Run integration tests + fees Run fees test + revert Run revert tests + recovery Run recovery tests + upgrade Run upgrade tests + build Build all test dependencies + rust Run unit-tests, accepts optional cargo test flags + l1-contracts Run L1 contracts tests + prover Run prover tests + wallet Print test wallets information + loadtest Run loadtest + help Print this message or the help of the given subcommand(s) +``` + +### Running unit tests + +You can run unit tests for the Rust crates in the project by running: + +```bash +zkstack dev test rust +``` + +### Running integration tests + +Running integration tests is more complex. Some tests require a running server, while others need the system to be in a +specific state. Please refer to our CI scripts +[ci-core-reusable.yml](https://github.com/matter-labs/zksync-era/blob/main/.github/workflows/ci-core-reusable.yml) to +have a better understanding of the process. + +### Running load tests + +The current load test implementation only supports the legacy bridge. To use it, you need to create a new chain with +legacy bridge support: + +```bash +zkstack chain create --legacy-bridge +zkstack chain init +``` + +After initializing the chain with a legacy bridge, you can run the load test against it. + +```bash +zkstack dev test loadtest +``` + +> WARNING: Never use legacy bridges in non-testing environments. + +## Contracts + +### Build contracts + +Run: + +```bash +zkstack dev contracts --help +``` + +to see all the options. + +### Publish source code on Etherscan + +#### Verifier Options + +Most commands interacting with smart contracts support the same verification options as Foundry's `forge` command. Just +double check if the following options are available in the subcommand: + +```bash +--verifier -- Verifier to use +--verifier-api-key -- Verifier API key +--verifier-url -- Verifier URL, if using a custom provider +``` + +#### Using Foundry + +You can use `foundry` to verify the source code of the contracts. + +```bash +forge verify-contract +``` + +Verifies a smart contract on a chosen verification provider. + +You must provide: + +- The contract address +- The contract name or the path to the contract. +- In case of Etherscan verification, you must also provide: + - Your Etherscan API key, either by passing it as an argument or setting `ETHERSCAN_API_KEY` + +For more information check [Foundry's documentation](https://book.getfoundry.sh/reference/forge/forge-verify-contract). diff --git a/docs/guides/external-node/00_quick_start.md b/docs/src/guides/external-node/00_quick_start.md similarity index 100% rename from docs/guides/external-node/00_quick_start.md rename to docs/src/guides/external-node/00_quick_start.md diff --git a/docs/guides/external-node/01_intro.md b/docs/src/guides/external-node/01_intro.md similarity index 100% rename from docs/guides/external-node/01_intro.md rename to docs/src/guides/external-node/01_intro.md diff --git a/docs/guides/external-node/02_configuration.md b/docs/src/guides/external-node/02_configuration.md similarity index 100% rename from docs/guides/external-node/02_configuration.md rename to docs/src/guides/external-node/02_configuration.md diff --git a/docs/guides/external-node/03_running.md b/docs/src/guides/external-node/03_running.md similarity index 100% rename from docs/guides/external-node/03_running.md rename to docs/src/guides/external-node/03_running.md diff --git a/docs/guides/external-node/04_observability.md b/docs/src/guides/external-node/04_observability.md similarity index 100% rename from docs/guides/external-node/04_observability.md rename to docs/src/guides/external-node/04_observability.md diff --git a/docs/guides/external-node/05_troubleshooting.md b/docs/src/guides/external-node/05_troubleshooting.md similarity index 100% rename from docs/guides/external-node/05_troubleshooting.md rename to docs/src/guides/external-node/05_troubleshooting.md diff --git a/docs/guides/external-node/06_components.md b/docs/src/guides/external-node/06_components.md similarity index 100% rename from docs/guides/external-node/06_components.md rename to docs/src/guides/external-node/06_components.md diff --git a/docs/guides/external-node/07_snapshots_recovery.md b/docs/src/guides/external-node/07_snapshots_recovery.md similarity index 100% rename from docs/guides/external-node/07_snapshots_recovery.md rename to docs/src/guides/external-node/07_snapshots_recovery.md diff --git a/docs/guides/external-node/08_pruning.md b/docs/src/guides/external-node/08_pruning.md similarity index 100% rename from docs/guides/external-node/08_pruning.md rename to docs/src/guides/external-node/08_pruning.md diff --git a/docs/guides/external-node/09_treeless_mode.md b/docs/src/guides/external-node/09_treeless_mode.md similarity index 100% rename from docs/guides/external-node/09_treeless_mode.md rename to docs/src/guides/external-node/09_treeless_mode.md diff --git a/docs/src/guides/external-node/10_decentralization.md b/docs/src/guides/external-node/10_decentralization.md new file mode 100644 index 000000000000..41f59486bef6 --- /dev/null +++ b/docs/src/guides/external-node/10_decentralization.md @@ -0,0 +1,91 @@ +# Decentralization + +In the default setup, the ZKsync node will fetch data from the ZKsync API endpoint maintained by Matter Labs. To reduce +the reliance on this centralized endpoint we have developed a decentralized p2p networking stack (aka gossipnet) which +will eventually be used instead of ZKsync API for synchronizing data. + +On the gossipnet, the data integrity will be protected by the BFT (byzantine fault-tolerant) consensus algorithm +(currently data is signed just by the main node though). + +## Enabling gossipnet on your node + +> [!NOTE] +> +> Because the data transmitted over the gossipnet is signed by the main node (and eventually by the consensus quorum), +> the signatures need to be backfilled to the node's local storage the first time you switch from centralized (ZKsync +> API based) synchronization to the decentralized (gossipnet based) synchronization (this is a one-time thing). With the +> current implementation it may take a couple of hours and gets faster the more nodes you add to the +> `gossip_static_outbound` list (see below). We are working to remove this inconvenience. + +> [!NOTE] +> +> The minimal supported server version for this is +> [24.11.0](https://github.com/matter-labs/zksync-era/releases/tag/core-v24.11.0) + +### Generating secrets + +Each participant node of the gossipnet has to have an identity (a public/secret key pair). When running your node for +the first time, generate the secrets by running: + +``` +docker run --entrypoint /usr/bin/zksync_external_node "matterlabs/external-node:2.0-v24.12.0" generate-secrets > consensus_secrets.yaml +chmod 600 consensus_secrets.yaml +``` + +> [!NOTE] +> +> NEVER reveal the secret keys used by your node. Otherwise, someone can impersonate your node on the gossipnet. If you +> suspect that your secret key has been leaked, you can generate fresh keys using the same tool. +> +> If you want someone else to connect to your node, give them your PUBLIC key instead. Both public and secret keys are +> present in the `consensus_secrets.yaml` (public keys are in comments). + +### Preparing configuration file + +Copy the template of the consensus configuration file (for +[mainnet](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/prepared_configs/mainnet_consensus_config.yaml) +or +[testnet](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/prepared_configs/testnet_consensus_config.yaml) +). + +> [!NOTE] +> +> You need to fill in the `public_addr` field. This is the address that will (not implemented yet) be advertised over +> gossipnet to other nodes, so that they can establish connections to your node. If you don't want to expose your node +> to the public internet, you can use IP in your local network. + +Currently the config contains the following fields (refer to config +[schema](https://github.com/matter-labs/zksync-era/blob/990676c5f84afd2ff8cd337f495c82e8d1f305a4/core/lib/protobuf_config/src/proto/core/consensus.proto#L66) +for more details): + +- `server_addr` - local TCP socket address that the node should listen on for incoming connections. Note that this is an + additional TCP port that will be opened by the node. +- `public_addr` - the public address of your node that will be advertised over the gossipnet. +- `max_payload_size` - limit (in bytes) on the sized of the ZKsync ERA block received from the gossipnet. This protects + your node from getting DoS`ed by too large network messages. Use the value from the template. +- `gossip_dynamic_inbound_limit` - maximal number of unauthenticated concurrent inbound connections that can be + established to your node. This is a DDoS protection measure. +- `gossip_static_outbound` - list of trusted peers that your node should always try to connect to. The template contains + the nodes maintained by Matterlabs, but you can add more if you know any. Note that the list contains both the network + address AND the public key of the node - this prevents spoofing attacks. + +### Setting environment variables + +Uncomment (or add) the following lines in your `.env` config: + +``` +EN_CONSENSUS_CONFIG_PATH=... +EN_CONSENSUS_SECRETS_PATH=... +``` + +These variables should point to your consensus config and secrets files that we have just created. Tweak the paths to +the files if you have placed them differently. + +### Add `--enable-consensus` flag to your entry point command + +For the consensus configuration to take effect you have to add `--enable-consensus` flag to the command line when +running the node, for example: + +``` +docker run "matterlabs/external-node:2.0-v24.12.0" --enable-consensus +``` diff --git a/docs/src/guides/external-node/README.md b/docs/src/guides/external-node/README.md new file mode 100644 index 000000000000..becd9846d4f2 --- /dev/null +++ b/docs/src/guides/external-node/README.md @@ -0,0 +1 @@ +# External node diff --git a/docs/guides/external-node/docker-compose-examples/configs/generate_secrets.sh b/docs/src/guides/external-node/docker-compose-examples/configs/generate_secrets.sh similarity index 100% rename from docs/guides/external-node/docker-compose-examples/configs/generate_secrets.sh rename to docs/src/guides/external-node/docker-compose-examples/configs/generate_secrets.sh diff --git a/docs/src/guides/external-node/docker-compose-examples/configs/mainnet_consensus_config.yaml b/docs/src/guides/external-node/docker-compose-examples/configs/mainnet_consensus_config.yaml new file mode 100644 index 000000000000..08f5861daa83 --- /dev/null +++ b/docs/src/guides/external-node/docker-compose-examples/configs/mainnet_consensus_config.yaml @@ -0,0 +1,5 @@ +server_addr: '0.0.0.0:3054' +public_addr: '127.0.0.1:3054' +debug_page_addr: '0.0.0.0:5000' +max_payload_size: 5000000 +gossip_dynamic_inbound_limit: 100 diff --git a/docs/src/guides/external-node/docker-compose-examples/configs/testnet_consensus_config.yaml b/docs/src/guides/external-node/docker-compose-examples/configs/testnet_consensus_config.yaml new file mode 100644 index 000000000000..08f5861daa83 --- /dev/null +++ b/docs/src/guides/external-node/docker-compose-examples/configs/testnet_consensus_config.yaml @@ -0,0 +1,5 @@ +server_addr: '0.0.0.0:3054' +public_addr: '127.0.0.1:3054' +debug_page_addr: '0.0.0.0:5000' +max_payload_size: 5000000 +gossip_dynamic_inbound_limit: 100 diff --git a/docs/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/Consensus.json b/docs/src/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/Consensus.json similarity index 100% rename from docs/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/Consensus.json rename to docs/src/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/Consensus.json diff --git a/docs/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/General.json b/docs/src/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/General.json similarity index 100% rename from docs/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/General.json rename to docs/src/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/General.json diff --git a/docs/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/default.yml b/docs/src/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/default.yml similarity index 100% rename from docs/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/default.yml rename to docs/src/guides/external-node/docker-compose-examples/grafana/provisioning/dashboards/default.yml diff --git a/docs/guides/external-node/docker-compose-examples/grafana/provisioning/datasources/prometheus.yml b/docs/src/guides/external-node/docker-compose-examples/grafana/provisioning/datasources/prometheus.yml similarity index 100% rename from docs/guides/external-node/docker-compose-examples/grafana/provisioning/datasources/prometheus.yml rename to docs/src/guides/external-node/docker-compose-examples/grafana/provisioning/datasources/prometheus.yml diff --git a/docs/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 similarity index 97% rename from docs/guides/external-node/docker-compose-examples/mainnet-external-node-docker-compose.yml rename to docs/src/guides/external-node/docker-compose-examples/mainnet-external-node-docker-compose.yml index 9c8c5bb31425..5ee9de187bf0 100644 --- a/docs/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-v24.16.0" + image: "matterlabs/external-node:2.0-v25.1.0" 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-v25.1.0" entrypoint: [ "/usr/bin/entrypoint.sh", diff --git a/docs/guides/external-node/docker-compose-examples/prometheus/prometheus.yml b/docs/src/guides/external-node/docker-compose-examples/prometheus/prometheus.yml similarity index 100% rename from docs/guides/external-node/docker-compose-examples/prometheus/prometheus.yml rename to docs/src/guides/external-node/docker-compose-examples/prometheus/prometheus.yml diff --git a/docs/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 similarity index 100% rename from docs/guides/external-node/docker-compose-examples/testnet-external-node-docker-compose.yml rename to docs/src/guides/external-node/docker-compose-examples/testnet-external-node-docker-compose.yml diff --git a/docs/guides/external-node/prepared_configs/mainnet-config.env b/docs/src/guides/external-node/prepared_configs/mainnet-config.env similarity index 98% rename from docs/guides/external-node/prepared_configs/mainnet-config.env rename to docs/src/guides/external-node/prepared_configs/mainnet-config.env index bce812084665..eac24f4ab7ed 100644 --- a/docs/guides/external-node/prepared_configs/mainnet-config.env +++ b/docs/src/guides/external-node/prepared_configs/mainnet-config.env @@ -70,7 +70,7 @@ RUST_LOG=zksync_core=debug,zksync_dal=info,zksync_eth_client=info,zksync_merkle_ RUST_BACKTRACE=full RUST_LIB_BACKTRACE=1 -# Settings related to gossip network, see `09_decentralization.md` +# Settings related to gossip network, see `10_decentralization.md` #EN_CONSENSUS_CONFIG_PATH=./mainnet_consensus_config.yaml #EN_CONSENSUS_SECRETS_PATH=./consensus_secrets.yaml diff --git a/docs/src/guides/external-node/prepared_configs/mainnet_consensus_config.yaml b/docs/src/guides/external-node/prepared_configs/mainnet_consensus_config.yaml new file mode 100644 index 000000000000..08347a14efa0 --- /dev/null +++ b/docs/src/guides/external-node/prepared_configs/mainnet_consensus_config.yaml @@ -0,0 +1,4 @@ +server_addr: '0.0.0.0:3054' +public_addr: ':3054' +max_payload_size: 5000000 +gossip_dynamic_inbound_limit: 100 diff --git a/docs/guides/external-node/prepared_configs/testnet-goerli-config-deprecated.env b/docs/src/guides/external-node/prepared_configs/testnet-goerli-config-deprecated.env similarity index 100% rename from docs/guides/external-node/prepared_configs/testnet-goerli-config-deprecated.env rename to docs/src/guides/external-node/prepared_configs/testnet-goerli-config-deprecated.env diff --git a/docs/guides/external-node/prepared_configs/testnet-sepolia-config.env b/docs/src/guides/external-node/prepared_configs/testnet-sepolia-config.env similarity index 98% rename from docs/guides/external-node/prepared_configs/testnet-sepolia-config.env rename to docs/src/guides/external-node/prepared_configs/testnet-sepolia-config.env index 182012e2850c..c8f855b4a4a2 100644 --- a/docs/guides/external-node/prepared_configs/testnet-sepolia-config.env +++ b/docs/src/guides/external-node/prepared_configs/testnet-sepolia-config.env @@ -70,7 +70,7 @@ RUST_LOG=zksync_core=debug,zksync_dal=info,zksync_eth_client=info,zksync_merkle_ RUST_BACKTRACE=full RUST_LIB_BACKTRACE=1 -# Settings related to gossip network, see `09_decentralization.md` +# Settings related to gossip network, see `10_decentralization.md` #EN_CONSENSUS_CONFIG_PATH=./testnet_consensus_config.yaml #EN_CONSENSUS_SECRETS_PATH=./consensus_secrets.yaml diff --git a/docs/src/guides/external-node/prepared_configs/testnet_consensus_config.yaml b/docs/src/guides/external-node/prepared_configs/testnet_consensus_config.yaml new file mode 100644 index 000000000000..08347a14efa0 --- /dev/null +++ b/docs/src/guides/external-node/prepared_configs/testnet_consensus_config.yaml @@ -0,0 +1,4 @@ +server_addr: '0.0.0.0:3054' +public_addr: ':3054' +max_payload_size: 5000000 +gossip_dynamic_inbound_limit: 100 diff --git a/docs/src/guides/launch.md b/docs/src/guides/launch.md new file mode 100644 index 000000000000..52872a53cf2a --- /dev/null +++ b/docs/src/guides/launch.md @@ -0,0 +1,202 @@ +# Running the application + +This document covers common scenarios for launching ZKsync applications set locally. + +## Prerequisites + +Prepare dev environment prerequisites: see + +[Installing dependencies](./setup-dev.md) + +## Setup local dev environment + +Run the required containers with: + +```bash +zkstack containers +``` + +Setup: + +```bash +zkstack ecosystem init +``` + +To completely reset the dev environment: + +- Stop services: + + ```bash + zkstack dev clean all + ``` + +- Repeat the setup procedure above + + ```bash + zkstack containers + zkstack ecosystem init + ``` + +### Run observability stack + +If you want to run [Dockprom](https://github.com/stefanprodan/dockprom/) stack (Prometheus, Grafana) alongside other +containers - add `--observability` parameter during initialisation. + +```bash +zkstack containers --observability +``` + +or select `yes` when prompted during the interactive execution of the command. + +That will also provision Grafana with +[era-observability](https://github.com/matter-labs/era-observability/tree/main/dashboards) dashboards. You can then +access it at `http://127.0.0.1:3000/` under credentials `admin/admin`. + +> If you don't see any data displayed on the Grafana dashboards - try setting the timeframe to "Last 30 minutes". You +> will also have to have `jq` installed on your system. + +## Ecosystem Configuration + +The ecosystem configuration is spread across multiple files and directories: + +1. Root level: + + - `ZkStack.yaml`: Main configuration file for the entire ecosystem. + +2. `configs/` directory: + + - `apps/`: + - `portal_config.json`: Configuration for the portal application. + - `contracts.yaml`: Defines smart contract settings and addresses. + - `erc20.yaml`: Configuration for ERC20 tokens. + - `initial_deployments.yaml`: Specifies initial ERC20 token deployments. + - `wallets.yaml`: Contains wallet configurations. + +3. `chains//` directory: + + - `artifacts/`: Contains build/execution artifacts. + - `configs/`: Chain-specific configuration files. + - `contracts.yaml`: Chain-specific smart contract settings. + - `external_node.yaml`: Configuration for external nodes. + - `general.yaml`: General chain configuration. + - `genesis.yaml`: Genesis configuration for the chain. + - `secrets.yaml`: Secrets and private keys for the chain. + - `wallets.yaml`: Wallet configurations for the chain. + - `db/main/`: Database files for the chain. + - `ZkStack.yaml`: Chain-specific ZkStack configuration. + +These configuration files are automatically generated during the ecosystem initialization (`zkstack ecosystem init`) and +chain initialization (`zkstack chain init`) processes. They control various aspects of the ZKsync ecosystem, including: + +- Network settings +- Smart contract deployments +- Token configurations +- Database settings +- Application/Service-specific parameters + +It's important to note that while these files can be manually edited, any changes may be overwritten if the ecosystem or +chain is reinitialized. Always back up your modifications and exercise caution when making direct changes to these +files. + +For specific configuration needs, it's recommended to use the appropriate `zkstack` commands or consult the +documentation for safe ways to customize your setup. + +## Build and run server + +Run server: + +```bash +zkstack server +``` + +The server's configuration files can be found in `/chains//configs` directory. These files are created when +running `zkstack chain init` command. + +### Modifying configuration files manually + +To manually modify configuration files: + +1. Locate the relevant config file in `/chains//configs` +2. Open the file in a text editor +3. Make necessary changes, following the existing format +4. Save the file +5. Restart the relevant services for changes to take effect: + +```bash +zkstack server +``` + +> NOTE: Manual changes to configuration files may be overwritten if the ecosystem is reinitialized or the chain is +> reinitialized. + +> WARNING: Some properties, such as ports, may require manual modification across different configuration files to +> ensure consistency and avoid conflicts. + +## Running server using Google cloud storage object store instead of default In memory store + +Get the `service_account.json` file containing the GCP credentials from kubernetes secret for relevant +environment(stage2/ testnet2) add that file to the default location `~/gcloud/service_account.json` or update +`object_store.toml` with the file location + +```bash +zkstack prover init --bucket-base-url={url} --credentials-file={path/to/service_account.json} +``` + +## Running prover server + +Running on a machine with GPU + +```bash +zkstack prover run --component=prover +``` + +> NOTE: Running on machine without GPU is currently not supported by `zkstack`. + +## Running the verification key generator + +```bash +# ensure that the setup_2^26.key in the current directory, the file can be download from https://storage.googleapis.com/matterlabs-setup-keys-us/setup-keys/setup_2\^26.key + +# To generate all verification keys +cargo run --release --bin zksync_verification_key_generator +``` + +## Generating binary verification keys for existing json verification keys + +```bash +cargo run --release --bin zksync_json_to_binary_vk_converter -- -o /path/to/output-binary-vk +``` + +## Generating commitment for existing verification keys + +```bash +cargo run --release --bin zksync_commitment_generator +``` + +## Running the contract verifier + +```bash +zkstack contract-verifier run +``` + +## Troubleshooting + +### Connection Refused + +#### Problem + +```bash +error sending request for url (http://127.0.0.1:8545/): error trying to connect: tcp connect error: Connection refused (os error 61) +``` + +#### Description + +It appears that no containers are currently running, which is likely the reason you're encountering this error. + +#### Solution + +Ensure that the necessary containers have been started and are functioning correctly to resolve the issue. + +```bash +zkstack containers +``` diff --git a/docs/guides/repositories.md b/docs/src/guides/repositories.md similarity index 100% rename from docs/guides/repositories.md rename to docs/src/guides/repositories.md diff --git a/docs/guides/setup-dev.md b/docs/src/guides/setup-dev.md similarity index 84% rename from docs/guides/setup-dev.md rename to docs/src/guides/setup-dev.md index 4eef211cd3d1..43350ac3314d 100644 --- a/docs/guides/setup-dev.md +++ b/docs/src/guides/setup-dev.md @@ -14,20 +14,20 @@ git config --global url."https://".insteadOf git:// # Rust curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + # NVM curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash + # All necessary stuff sudo apt-get update -sudo apt-get install build-essential pkg-config cmake clang lldb lld libssl-dev postgresql apt-transport-https ca-certificates curl software-properties-common +sudo apt-get install -y build-essential pkg-config cmake clang lldb lld libssl-dev libpq-dev apt-transport-https ca-certificates curl software-properties-common + # Install docker curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable" sudo apt install docker-ce sudo usermod -aG docker ${USER} -# Stop default postgres (as we'll use the docker one) -sudo systemctl stop postgresql -sudo systemctl disable postgresql # Start docker. sudo systemctl start docker @@ -45,9 +45,9 @@ cargo install cargo-nextest # SQL tools cargo install sqlx-cli --version 0.8.1 -# Foundry -curl -L https://foundry.paradigm.xyz | bash -foundryup --branch master +# Foundry ZKsync +curl -L https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/install-foundry-zksync | bash +foundryup-zksync # Non CUDA (GPU) setup, can be skipped if the machine has a CUDA installed for provers # Don't do that if you intend to run provers on your machine. Check the prover docs for a setup instead. @@ -60,24 +60,24 @@ cd zksync-era git submodule update --init --recursive ``` -Don't forget to [add env variables](#Environment) and look at [tips](#tips). +Don't forget to look at [tips](#tips). ## Supported operating systems -ZKsync currently can be launched on any \*nix operating system (e.g. any linux distribution or MacOS). +ZKsync currently can be launched on any \*nix operating system (e.g. any linux distribution or macOS). If you're using Windows, then make sure to use WSL 2. Additionally, if you are going to use WSL 2, make sure that your project is located in the _linux filesystem_, since accessing NTFS partitions from within WSL is very slow. -If you're using MacOS with an ARM processor (e.g. M1/M2), make sure that you are working in the _native_ environment -(e.g. your terminal and IDE don't run in Rosetta, and your toolchain is native). Trying to work with ZKsync code via +If you're using macOS with an ARM processor (e.g. M1/M2), make sure that you are working in the _native_ environment +(e.g., your terminal and IDE don't run in Rosetta, and your toolchain is native). Trying to work with ZKsync code via Rosetta may cause problems that are hard to spot and debug, so make sure to check everything before you start. If you are a NixOS user or would like to have a reproducible environment, skip to the section about `nix`. -## `Docker` +## Docker Install `docker`. It is recommended to follow the instructions from the [official site](https://docs.docker.com/install/). @@ -117,13 +117,13 @@ at this step. If logging out does not resolve the issue, restarting the computer should. -## `Node` & `Yarn` +## Node.js & Yarn 1. Install `Node` (requires version `v20`). The recommended way is via [nvm](https://github.com/nvm-sh/nvm). 2. Install `yarn`. Can be done via `npm install -g yarn`. Make sure to get version 1.22.19 - you can change the version by running `yarn set version 1.22.19`. -## `clang` +## clang In order to compile RocksDB, you must have LLVM available. On debian-based linux it can be installed as follows: @@ -133,12 +133,12 @@ On debian-based linux: sudo apt-get install build-essential pkg-config cmake clang lldb lld ``` -On mac: +On macOS: You need to have an up-to-date `Xcode`. You can install it directly from `App Store`. With Xcode command line tools, you get the Clang compiler installed by default. Thus, having XCode you don't need to install `clang`. -## `OpenSSL` +## OpenSSL Install OpenSSL: @@ -154,9 +154,9 @@ On debian-based linux: sudo apt-get install libssl-dev ``` -## `Rust` +## Rust -Install the latest `rust` version. +Install `Rust`'s toolchain version reported in `/rust-toolchain.toml` (also a later stable version should work). Instructions can be found on the [official site](https://www.rust-lang.org/tools/install). @@ -167,7 +167,7 @@ rustc --version rustc 1.xx.y (xxxxxx 20xx-yy-zz) # Output may vary depending on actual version of rust ``` -If you are using MacOS with ARM processor (e.g. M1/M2), make sure that you use an `aarch64` toolchain. For example, when +If you are using macOS with ARM processor (e.g. M1/M2), make sure that you use an `aarch64` toolchain. For example, when you run `rustup show`, you should see a similar input: ```bash @@ -190,25 +190,26 @@ If you see `x86_64` mentioned in the output, probably you're running (or used to that's the case, you should probably change the way you run terminal, and/or reinstall your IDE, and then reinstall the Rust toolchain as well. -## Postgres +## PostgreSQL Client Library -Install the latest postgres: +For development purposes, you typically only need the PostgreSQL client library, not the full server installation. +Here's how to install it: -On mac: +On macOS: ```bash -brew install postgresql@14 +brew install libpq ``` -On debian-based linux: +On Debian-based Linux: ```bash -sudo apt-get install postgresql +sudo apt-get install libpq-dev ``` ### Cargo nextest -[cargo-nextest](https://nexte.st/) is the next-generation test runner for Rust projects. `zk test rust` uses +[cargo-nextest](https://nexte.st/) is the next-generation test runner for Rust projects. `zkstack dev test rust` uses `cargo nextest` by default. ```bash @@ -236,10 +237,13 @@ enable nix-ld. Go to the zksync folder and run `nix develop`. After it finishes, you are in a shell that has all the dependencies. -## Foundry +## Foundry ZKsync + +ZKSync depends on Foundry ZKsync (which is is a specialized fork of Foundry, tailored for ZKsync). Please follow this +[installation guide](https://foundry-book.zksync.io/getting-started/installation) to get started with Foundry ZKsync. -[Foundry](https://book.getfoundry.sh/getting-started/installation) can be utilized for deploying smart contracts. For -commands related to deployment, you can pass flags for Foundry integration. +Foundry ZKsync can also be used for deploying smart contracts. For commands related to deployment, you can pass flags +for Foundry integration. ## Non-GPU setup @@ -266,17 +270,6 @@ RUSTFLAGS as env var, or pass it in `config.toml` (either project level or globa rustflags = ["--cfg=no_cuda"] ``` -## Environment - -Edit the lines below and add them to your shell profile file (e.g. `~/.bash_profile`, `~/.zshrc`): - -```bash -# Add path here: -export ZKSYNC_HOME=/path/to/zksync - -export PATH=$ZKSYNC_HOME/bin:$PATH -``` - ## Tips ### Tip: `mold` @@ -294,7 +287,7 @@ export RUSTFLAGS='-C link-arg=-fuse-ld=/usr/local/bin/mold' export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER="clang" ``` -## Tip: Speeding up building `RocksDB` +### Tip: Speeding up building `RocksDB` By default, each time you compile `rocksdb` crate, it will compile required C++ sources from scratch. It can be avoided by using precompiled versions of library, and it will significantly improve your build times. diff --git a/docs/src/misc/contributors.md b/docs/src/misc/contributors.md new file mode 100644 index 000000000000..77e81149e465 --- /dev/null +++ b/docs/src/misc/contributors.md @@ -0,0 +1 @@ +# Contributors diff --git a/docs/specs/README.md b/docs/src/specs/README.md similarity index 100% rename from docs/specs/README.md rename to docs/src/specs/README.md diff --git a/docs/specs/blocks_batches.md b/docs/src/specs/blocks_batches.md similarity index 100% rename from docs/specs/blocks_batches.md rename to docs/src/specs/blocks_batches.md diff --git a/docs/specs/data_availability/README.md b/docs/src/specs/data_availability/README.md similarity index 100% rename from docs/specs/data_availability/README.md rename to docs/src/specs/data_availability/README.md diff --git a/docs/specs/data_availability/compression.md b/docs/src/specs/data_availability/compression.md similarity index 100% rename from docs/specs/data_availability/compression.md rename to docs/src/specs/data_availability/compression.md diff --git a/docs/specs/data_availability/overview.md b/docs/src/specs/data_availability/overview.md similarity index 100% rename from docs/specs/data_availability/overview.md rename to docs/src/specs/data_availability/overview.md diff --git a/docs/specs/data_availability/pubdata.md b/docs/src/specs/data_availability/pubdata.md similarity index 100% rename from docs/specs/data_availability/pubdata.md rename to docs/src/specs/data_availability/pubdata.md diff --git a/docs/specs/data_availability/reconstruction.md b/docs/src/specs/data_availability/reconstruction.md similarity index 100% rename from docs/specs/data_availability/reconstruction.md rename to docs/src/specs/data_availability/reconstruction.md diff --git a/docs/specs/data_availability/validium_zk_porter.md b/docs/src/specs/data_availability/validium_zk_porter.md similarity index 100% rename from docs/specs/data_availability/validium_zk_porter.md rename to docs/src/specs/data_availability/validium_zk_porter.md diff --git a/docs/specs/img/L2_Components.png b/docs/src/specs/img/L2_Components.png similarity index 100% rename from docs/specs/img/L2_Components.png rename to docs/src/specs/img/L2_Components.png diff --git a/docs/specs/img/diamondProxy.jpg b/docs/src/specs/img/diamondProxy.jpg similarity index 100% rename from docs/specs/img/diamondProxy.jpg rename to docs/src/specs/img/diamondProxy.jpg diff --git a/docs/specs/img/governance.jpg b/docs/src/specs/img/governance.jpg similarity index 100% rename from docs/specs/img/governance.jpg rename to docs/src/specs/img/governance.jpg diff --git a/docs/specs/img/zk-the-collective-action.jpeg b/docs/src/specs/img/zk-the-collective-action.jpeg similarity index 100% rename from docs/specs/img/zk-the-collective-action.jpeg rename to docs/src/specs/img/zk-the-collective-action.jpeg diff --git a/docs/specs/introduction.md b/docs/src/specs/introduction.md similarity index 100% rename from docs/specs/introduction.md rename to docs/src/specs/introduction.md diff --git a/docs/specs/l1_l2_communication/README.md b/docs/src/specs/l1_l2_communication/README.md similarity index 100% rename from docs/specs/l1_l2_communication/README.md rename to docs/src/specs/l1_l2_communication/README.md diff --git a/docs/specs/l1_l2_communication/l1_to_l2.md b/docs/src/specs/l1_l2_communication/l1_to_l2.md similarity index 100% rename from docs/specs/l1_l2_communication/l1_to_l2.md rename to docs/src/specs/l1_l2_communication/l1_to_l2.md diff --git a/docs/specs/l1_l2_communication/l2_to_l1.md b/docs/src/specs/l1_l2_communication/l2_to_l1.md similarity index 100% rename from docs/specs/l1_l2_communication/l2_to_l1.md rename to docs/src/specs/l1_l2_communication/l2_to_l1.md diff --git a/docs/specs/l1_l2_communication/overview_deposits_withdrawals.md b/docs/src/specs/l1_l2_communication/overview_deposits_withdrawals.md similarity index 100% rename from docs/specs/l1_l2_communication/overview_deposits_withdrawals.md rename to docs/src/specs/l1_l2_communication/overview_deposits_withdrawals.md diff --git a/docs/specs/l1_smart_contracts.md b/docs/src/specs/l1_smart_contracts.md similarity index 100% rename from docs/specs/l1_smart_contracts.md rename to docs/src/specs/l1_smart_contracts.md diff --git a/docs/specs/overview.md b/docs/src/specs/overview.md similarity index 100% rename from docs/specs/overview.md rename to docs/src/specs/overview.md diff --git a/docs/specs/prover/README.md b/docs/src/specs/prover/README.md similarity index 100% rename from docs/specs/prover/README.md rename to docs/src/specs/prover/README.md diff --git a/docs/specs/prover/boojum_function_check_if_satisfied.md b/docs/src/specs/prover/boojum_function_check_if_satisfied.md similarity index 100% rename from docs/specs/prover/boojum_function_check_if_satisfied.md rename to docs/src/specs/prover/boojum_function_check_if_satisfied.md diff --git a/docs/specs/prover/boojum_gadgets.md b/docs/src/specs/prover/boojum_gadgets.md similarity index 100% rename from docs/specs/prover/boojum_gadgets.md rename to docs/src/specs/prover/boojum_gadgets.md diff --git a/docs/specs/prover/circuit_testing.md b/docs/src/specs/prover/circuit_testing.md similarity index 100% rename from docs/specs/prover/circuit_testing.md rename to docs/src/specs/prover/circuit_testing.md diff --git a/docs/specs/prover/circuits/README.md b/docs/src/specs/prover/circuits/README.md similarity index 100% rename from docs/specs/prover/circuits/README.md rename to docs/src/specs/prover/circuits/README.md diff --git a/docs/specs/prover/circuits/code_decommitter.md b/docs/src/specs/prover/circuits/code_decommitter.md similarity index 100% rename from docs/specs/prover/circuits/code_decommitter.md rename to docs/src/specs/prover/circuits/code_decommitter.md diff --git a/docs/specs/prover/circuits/demux_log_queue.md b/docs/src/specs/prover/circuits/demux_log_queue.md similarity index 100% rename from docs/specs/prover/circuits/demux_log_queue.md rename to docs/src/specs/prover/circuits/demux_log_queue.md diff --git a/docs/specs/prover/circuits/ecrecover.md b/docs/src/specs/prover/circuits/ecrecover.md similarity index 100% rename from docs/specs/prover/circuits/ecrecover.md rename to docs/src/specs/prover/circuits/ecrecover.md diff --git a/docs/specs/prover/circuits/img/diagram.png b/docs/src/specs/prover/circuits/img/diagram.png similarity index 100% rename from docs/specs/prover/circuits/img/diagram.png rename to docs/src/specs/prover/circuits/img/diagram.png diff --git a/docs/specs/prover/circuits/img/flowchart.png b/docs/src/specs/prover/circuits/img/flowchart.png similarity index 100% rename from docs/specs/prover/circuits/img/flowchart.png rename to docs/src/specs/prover/circuits/img/flowchart.png diff --git a/docs/specs/prover/circuits/img/image.png b/docs/src/specs/prover/circuits/img/image.png similarity index 100% rename from docs/specs/prover/circuits/img/image.png rename to docs/src/specs/prover/circuits/img/image.png diff --git a/docs/specs/prover/circuits/keccak_round_function.md b/docs/src/specs/prover/circuits/keccak_round_function.md similarity index 100% rename from docs/specs/prover/circuits/keccak_round_function.md rename to docs/src/specs/prover/circuits/keccak_round_function.md diff --git a/docs/specs/prover/circuits/l1_messages_hasher.md b/docs/src/specs/prover/circuits/l1_messages_hasher.md similarity index 100% rename from docs/specs/prover/circuits/l1_messages_hasher.md rename to docs/src/specs/prover/circuits/l1_messages_hasher.md diff --git a/docs/specs/prover/circuits/log_sorter.md b/docs/src/specs/prover/circuits/log_sorter.md similarity index 100% rename from docs/specs/prover/circuits/log_sorter.md rename to docs/src/specs/prover/circuits/log_sorter.md diff --git a/docs/specs/prover/circuits/main_vm.md b/docs/src/specs/prover/circuits/main_vm.md similarity index 100% rename from docs/specs/prover/circuits/main_vm.md rename to docs/src/specs/prover/circuits/main_vm.md diff --git a/docs/specs/prover/circuits/overview.md b/docs/src/specs/prover/circuits/overview.md similarity index 100% rename from docs/specs/prover/circuits/overview.md rename to docs/src/specs/prover/circuits/overview.md diff --git a/docs/specs/prover/circuits/ram_permutation.md b/docs/src/specs/prover/circuits/ram_permutation.md similarity index 100% rename from docs/specs/prover/circuits/ram_permutation.md rename to docs/src/specs/prover/circuits/ram_permutation.md diff --git a/docs/specs/prover/circuits/sha256_round_function.md b/docs/src/specs/prover/circuits/sha256_round_function.md similarity index 100% rename from docs/specs/prover/circuits/sha256_round_function.md rename to docs/src/specs/prover/circuits/sha256_round_function.md diff --git a/docs/specs/prover/circuits/sort_decommitments.md b/docs/src/specs/prover/circuits/sort_decommitments.md similarity index 100% rename from docs/specs/prover/circuits/sort_decommitments.md rename to docs/src/specs/prover/circuits/sort_decommitments.md diff --git a/docs/specs/prover/circuits/sorting.md b/docs/src/specs/prover/circuits/sorting.md similarity index 100% rename from docs/specs/prover/circuits/sorting.md rename to docs/src/specs/prover/circuits/sorting.md diff --git a/docs/specs/prover/circuits/sorting_and_deduplicating.md b/docs/src/specs/prover/circuits/sorting_and_deduplicating.md similarity index 100% rename from docs/specs/prover/circuits/sorting_and_deduplicating.md rename to docs/src/specs/prover/circuits/sorting_and_deduplicating.md diff --git a/docs/specs/prover/circuits/storage_application.md b/docs/src/specs/prover/circuits/storage_application.md similarity index 100% rename from docs/specs/prover/circuits/storage_application.md rename to docs/src/specs/prover/circuits/storage_application.md diff --git a/docs/specs/prover/circuits/storage_sorter.md b/docs/src/specs/prover/circuits/storage_sorter.md similarity index 100% rename from docs/specs/prover/circuits/storage_sorter.md rename to docs/src/specs/prover/circuits/storage_sorter.md diff --git a/docs/specs/prover/getting_started.md b/docs/src/specs/prover/getting_started.md similarity index 100% rename from docs/specs/prover/getting_started.md rename to docs/src/specs/prover/getting_started.md diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(1).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(1).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(1).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(1).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(11).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(11).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(11).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(11).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(12).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(12).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(12).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(12).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(13).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(13).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(13).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(13).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(14).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(14).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(14).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(14).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(16).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(16).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(16).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(16).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(17).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(17).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(17).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(17).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(2).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(2).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(2).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(2).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(3).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(3).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(3).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(3).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(4).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(4).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(4).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(4).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(7).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(7).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(7).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(7).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(8).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(8).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(8).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(8).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(9).png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(9).png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(9).png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied(9).png diff --git a/docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied.png b/docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied.png similarity index 100% rename from docs/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied.png rename to docs/src/specs/prover/img/boojum_function_check_if_satisfied/Check_if_satisfied.png diff --git a/docs/specs/prover/img/circuit_testing/Contest(10).png b/docs/src/specs/prover/img/circuit_testing/Contest(10).png similarity index 100% rename from docs/specs/prover/img/circuit_testing/Contest(10).png rename to docs/src/specs/prover/img/circuit_testing/Contest(10).png diff --git a/docs/specs/prover/img/circuit_testing/Contest(11).png b/docs/src/specs/prover/img/circuit_testing/Contest(11).png similarity index 100% rename from docs/specs/prover/img/circuit_testing/Contest(11).png rename to docs/src/specs/prover/img/circuit_testing/Contest(11).png diff --git a/docs/specs/prover/img/circuit_testing/Contest(12).png b/docs/src/specs/prover/img/circuit_testing/Contest(12).png similarity index 100% rename from docs/specs/prover/img/circuit_testing/Contest(12).png rename to docs/src/specs/prover/img/circuit_testing/Contest(12).png diff --git a/docs/specs/prover/img/circuit_testing/Contest(4).png b/docs/src/specs/prover/img/circuit_testing/Contest(4).png similarity index 100% rename from docs/specs/prover/img/circuit_testing/Contest(4).png rename to docs/src/specs/prover/img/circuit_testing/Contest(4).png diff --git a/docs/specs/prover/img/circuit_testing/Contest(5).png b/docs/src/specs/prover/img/circuit_testing/Contest(5).png similarity index 100% rename from docs/specs/prover/img/circuit_testing/Contest(5).png rename to docs/src/specs/prover/img/circuit_testing/Contest(5).png diff --git a/docs/specs/prover/img/circuit_testing/Contest(6).png b/docs/src/specs/prover/img/circuit_testing/Contest(6).png similarity index 100% rename from docs/specs/prover/img/circuit_testing/Contest(6).png rename to docs/src/specs/prover/img/circuit_testing/Contest(6).png diff --git a/docs/specs/prover/img/circuit_testing/Contest(7).png b/docs/src/specs/prover/img/circuit_testing/Contest(7).png similarity index 100% rename from docs/specs/prover/img/circuit_testing/Contest(7).png rename to docs/src/specs/prover/img/circuit_testing/Contest(7).png diff --git a/docs/specs/prover/img/circuit_testing/Contest(8).png b/docs/src/specs/prover/img/circuit_testing/Contest(8).png similarity index 100% rename from docs/specs/prover/img/circuit_testing/Contest(8).png rename to docs/src/specs/prover/img/circuit_testing/Contest(8).png diff --git a/docs/specs/prover/img/circuit_testing/Contest(9).png b/docs/src/specs/prover/img/circuit_testing/Contest(9).png similarity index 100% rename from docs/specs/prover/img/circuit_testing/Contest(9).png rename to docs/src/specs/prover/img/circuit_testing/Contest(9).png diff --git "a/docs/specs/prover/img/intro_to_zkSync\342\200\231s_ZK/circuit.png" "b/docs/src/specs/prover/img/intro_to_zkSync\342\200\231s_ZK/circuit.png" similarity index 100% rename from "docs/specs/prover/img/intro_to_zkSync\342\200\231s_ZK/circuit.png" rename to "docs/src/specs/prover/img/intro_to_zkSync\342\200\231s_ZK/circuit.png" diff --git a/docs/specs/prover/overview.md b/docs/src/specs/prover/overview.md similarity index 100% rename from docs/specs/prover/overview.md rename to docs/src/specs/prover/overview.md diff --git a/docs/specs/prover/zk_terminology.md b/docs/src/specs/prover/zk_terminology.md similarity index 100% rename from docs/specs/prover/zk_terminology.md rename to docs/src/specs/prover/zk_terminology.md diff --git a/docs/specs/zk_chains/README.md b/docs/src/specs/zk_chains/README.md similarity index 100% rename from docs/specs/zk_chains/README.md rename to docs/src/specs/zk_chains/README.md diff --git a/docs/specs/zk_chains/gateway.md b/docs/src/specs/zk_chains/gateway.md similarity index 100% rename from docs/specs/zk_chains/gateway.md rename to docs/src/specs/zk_chains/gateway.md diff --git a/docs/specs/zk_chains/img/contractsExternal.png b/docs/src/specs/zk_chains/img/contractsExternal.png similarity index 100% rename from docs/specs/zk_chains/img/contractsExternal.png rename to docs/src/specs/zk_chains/img/contractsExternal.png diff --git a/docs/specs/zk_chains/img/deployWeth.png b/docs/src/specs/zk_chains/img/deployWeth.png similarity index 100% rename from docs/specs/zk_chains/img/deployWeth.png rename to docs/src/specs/zk_chains/img/deployWeth.png diff --git a/docs/specs/zk_chains/img/depositWeth.png b/docs/src/specs/zk_chains/img/depositWeth.png similarity index 100% rename from docs/specs/zk_chains/img/depositWeth.png rename to docs/src/specs/zk_chains/img/depositWeth.png diff --git a/docs/specs/zk_chains/img/hyperbridges.png b/docs/src/specs/zk_chains/img/hyperbridges.png similarity index 100% rename from docs/specs/zk_chains/img/hyperbridges.png rename to docs/src/specs/zk_chains/img/hyperbridges.png diff --git a/docs/specs/zk_chains/img/hyperbridging.png b/docs/src/specs/zk_chains/img/hyperbridging.png similarity index 100% rename from docs/specs/zk_chains/img/hyperbridging.png rename to docs/src/specs/zk_chains/img/hyperbridging.png diff --git a/docs/specs/zk_chains/img/newChain.png b/docs/src/specs/zk_chains/img/newChain.png similarity index 100% rename from docs/specs/zk_chains/img/newChain.png rename to docs/src/specs/zk_chains/img/newChain.png diff --git a/docs/specs/zk_chains/interop.md b/docs/src/specs/zk_chains/interop.md similarity index 100% rename from docs/specs/zk_chains/interop.md rename to docs/src/specs/zk_chains/interop.md diff --git a/docs/specs/zk_chains/overview.md b/docs/src/specs/zk_chains/overview.md similarity index 100% rename from docs/specs/zk_chains/overview.md rename to docs/src/specs/zk_chains/overview.md diff --git a/docs/specs/zk_chains/shared_bridge.md b/docs/src/specs/zk_chains/shared_bridge.md similarity index 100% rename from docs/specs/zk_chains/shared_bridge.md rename to docs/src/specs/zk_chains/shared_bridge.md diff --git a/docs/specs/zk_evm/README.md b/docs/src/specs/zk_evm/README.md similarity index 100% rename from docs/specs/zk_evm/README.md rename to docs/src/specs/zk_evm/README.md diff --git a/docs/specs/zk_evm/account_abstraction.md b/docs/src/specs/zk_evm/account_abstraction.md similarity index 100% rename from docs/specs/zk_evm/account_abstraction.md rename to docs/src/specs/zk_evm/account_abstraction.md diff --git a/docs/specs/zk_evm/bootloader.md b/docs/src/specs/zk_evm/bootloader.md similarity index 100% rename from docs/specs/zk_evm/bootloader.md rename to docs/src/specs/zk_evm/bootloader.md diff --git a/docs/specs/zk_evm/fee_model.md b/docs/src/specs/zk_evm/fee_model.md similarity index 100% rename from docs/specs/zk_evm/fee_model.md rename to docs/src/specs/zk_evm/fee_model.md diff --git a/docs/specs/zk_evm/precompiles.md b/docs/src/specs/zk_evm/precompiles.md similarity index 100% rename from docs/specs/zk_evm/precompiles.md rename to docs/src/specs/zk_evm/precompiles.md diff --git a/docs/specs/zk_evm/system_contracts.md b/docs/src/specs/zk_evm/system_contracts.md similarity index 100% rename from docs/specs/zk_evm/system_contracts.md rename to docs/src/specs/zk_evm/system_contracts.md diff --git a/docs/specs/zk_evm/vm_overview.md b/docs/src/specs/zk_evm/vm_overview.md similarity index 100% rename from docs/specs/zk_evm/vm_overview.md rename to docs/src/specs/zk_evm/vm_overview.md diff --git a/docs/specs/zk_evm/vm_specification/EraVM_formal_specification.pdf b/docs/src/specs/zk_evm/vm_specification/EraVM_formal_specification.pdf similarity index 100% rename from docs/specs/zk_evm/vm_specification/EraVM_formal_specification.pdf rename to docs/src/specs/zk_evm/vm_specification/EraVM_formal_specification.pdf diff --git a/docs/specs/zk_evm/vm_specification/README.md b/docs/src/specs/zk_evm/vm_specification/README.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/README.md rename to docs/src/specs/zk_evm/vm_specification/README.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/README.md b/docs/src/specs/zk_evm/vm_specification/compiler/README.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/README.md rename to docs/src/specs/zk_evm/vm_specification/compiler/README.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/code_separation.md b/docs/src/specs/zk_evm/vm_specification/compiler/code_separation.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/code_separation.md rename to docs/src/specs/zk_evm/vm_specification/compiler/code_separation.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/evmla_translator.md b/docs/src/specs/zk_evm/vm_specification/compiler/evmla_translator.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/evmla_translator.md rename to docs/src/specs/zk_evm/vm_specification/compiler/evmla_translator.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/exception_handling.md b/docs/src/specs/zk_evm/vm_specification/compiler/exception_handling.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/exception_handling.md rename to docs/src/specs/zk_evm/vm_specification/compiler/exception_handling.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/README.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/README.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/README.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/README.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/README.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/README.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/README.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/README.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/arithmetic.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/arithmetic.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/arithmetic.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/arithmetic.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/bitwise.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/bitwise.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/bitwise.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/bitwise.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/block.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/block.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/block.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/block.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/call.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/call.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/call.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/call.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/create.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/create.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/create.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/create.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/environment.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/environment.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/environment.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/environment.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/logging.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/logging.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/logging.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/logging.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/logical.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/logical.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/logical.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/logical.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/memory.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/memory.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/memory.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/memory.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/overview.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/overview.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/overview.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/overview.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/return.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/return.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/return.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/return.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/sha3.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/sha3.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/sha3.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/sha3.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evm/stack.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/stack.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evm/stack.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evm/stack.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/evmla.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/evmla.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/evmla.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/evmla.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/extensions/README.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/extensions/README.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/extensions/README.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/extensions/README.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/extensions/call.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/extensions/call.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/extensions/call.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/extensions/call.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/extensions/overview.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/extensions/overview.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/extensions/overview.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/extensions/overview.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/extensions/verbatim.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/extensions/verbatim.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/extensions/verbatim.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/extensions/verbatim.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/overview.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/overview.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/overview.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/overview.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/instructions/yul.md b/docs/src/specs/zk_evm/vm_specification/compiler/instructions/yul.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/instructions/yul.md rename to docs/src/specs/zk_evm/vm_specification/compiler/instructions/yul.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/overview.md b/docs/src/specs/zk_evm/vm_specification/compiler/overview.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/overview.md rename to docs/src/specs/zk_evm/vm_specification/compiler/overview.md diff --git a/docs/specs/zk_evm/vm_specification/compiler/system_contracts.md b/docs/src/specs/zk_evm/vm_specification/compiler/system_contracts.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/compiler/system_contracts.md rename to docs/src/specs/zk_evm/vm_specification/compiler/system_contracts.md diff --git a/docs/specs/zk_evm/vm_specification/img/arch-overview.png b/docs/src/specs/zk_evm/vm_specification/img/arch-overview.png similarity index 100% rename from docs/specs/zk_evm/vm_specification/img/arch-overview.png rename to docs/src/specs/zk_evm/vm_specification/img/arch-overview.png diff --git a/docs/specs/zk_evm/vm_specification/img/arithmetic_opcode.png b/docs/src/specs/zk_evm/vm_specification/img/arithmetic_opcode.png similarity index 100% rename from docs/specs/zk_evm/vm_specification/img/arithmetic_opcode.png rename to docs/src/specs/zk_evm/vm_specification/img/arithmetic_opcode.png diff --git a/docs/specs/zk_evm/vm_specification/zkSync_era_virtual_machine_primer.md b/docs/src/specs/zk_evm/vm_specification/zkSync_era_virtual_machine_primer.md similarity index 100% rename from docs/specs/zk_evm/vm_specification/zkSync_era_virtual_machine_primer.md rename to docs/src/specs/zk_evm/vm_specification/zkSync_era_virtual_machine_primer.md diff --git a/docs/theme/head.hbs b/docs/theme/head.hbs new file mode 100644 index 000000000000..66ee37538adf --- /dev/null +++ b/docs/theme/head.hbs @@ -0,0 +1 @@ + diff --git a/etc/lint-config/ignore.yaml b/etc/lint-config/ignore.yaml index b4456a6c3fd4..009d0dbb0946 100644 --- a/etc/lint-config/ignore.yaml +++ b/etc/lint-config/ignore.yaml @@ -24,5 +24,7 @@ dirs: [ "artifacts-zk", "cache-zk", "contracts/", - "era-observability" + "era-observability", + "docs/js", + "prover/docs/js" ] diff --git a/prover/Cargo.lock b/prover/Cargo.lock index 3250c99deda6..a60f77d44dd7 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -7816,6 +7816,7 @@ version = "0.1.0" dependencies = [ "anyhow", "chrono", + "const-decoder 0.4.0", "ethabi", "hex", "num_enum 0.7.2", @@ -7823,6 +7824,7 @@ dependencies = [ "serde", "serde_json", "serde_with", + "sha2 0.10.8", "strum", "thiserror", "tiny-keccak 2.0.2", @@ -7994,11 +7996,11 @@ name = "zksync_contracts" version = "0.1.0" dependencies = [ "envy", - "ethabi", "hex", "once_cell", "serde", "serde_json", + "zksync_basic_types", "zksync_utils", ] @@ -8076,7 +8078,6 @@ dependencies = [ "zksync_protobuf_build", "zksync_system_constants", "zksync_types", - "zksync_utils", "zksync_vm_interface", ] @@ -8230,7 +8231,6 @@ dependencies = [ "zksync_mini_merkle_tree", "zksync_system_constants", "zksync_types", - "zksync_utils", "zksync_vm2", "zksync_vm_interface", ] @@ -8622,7 +8622,6 @@ dependencies = [ "zksync_protobuf", "zksync_protobuf_build", "zksync_system_constants", - "zksync_utils", ] [[package]] @@ -8630,16 +8629,12 @@ name = "zksync_utils" version = "0.1.0" dependencies = [ "anyhow", - "const-decoder 0.4.0", "futures 0.3.30", "once_cell", "reqwest 0.12.5", "serde_json", - "thiserror", "tokio", "tracing", - "zk_evm 0.133.0", - "zksync_basic_types", "zksync_vlog", ] diff --git a/prover/crates/bin/prover_autoscaler/README.md b/prover/crates/bin/prover_autoscaler/README.md index 6a0ff84f88f2..3d1a9afe5a30 100644 --- a/prover/crates/bin/prover_autoscaler/README.md +++ b/prover/crates/bin/prover_autoscaler/README.md @@ -152,7 +152,8 @@ agent_config: - `protocol_versions` is a map namespaces to protocol version it processes. Should correspond binary versions running there! - `cluster_priorities` is a map cluster name to priority, the lower will be used first. -- `min_provers` is a map namespace to minimum number of provers to run even if the queue is empty. +- `apply_min_to_namespace` specifies current primary namespace to run min number of provers in it. +- `min_provers` is a minimum number of provers to run even if the queue is empty. Default: 0. - `max_provers` is a map of cluster name to map GPU type to maximum number of provers. - `prover_speed` is a map GPU to speed divider. Default: 500. - `long_pending_duration` is time after a pending pod considered long pending and will be relocated to different @@ -160,6 +161,7 @@ agent_config: - `scaler_targets` subsection is a list of Simple targets: - `queue_report_field` is name of corresponding queue report section. See example for possible options. - `deployment` is name of a Deployment to scale. + - `min_replicas` is a minimum number of replicas to run even if the queue is empty. Default: 0. - `max_replicas` is a map of cluster name to maximum number of replicas. - `speed` is a divider for corresponding queue. @@ -182,8 +184,8 @@ scaler_config: cluster1: 0 cluster2: 100 cluster3: 200 - min_provers: - prover-new: 0 + apply_min_to_namespace: prover-new + min_provers: 1 max_provers: cluster1: L4: 1 @@ -201,6 +203,7 @@ scaler_config: scaler_targets: - queue_report_field: basic_witness_jobs deployment: witness-generator-basic-fri + min_replicas: 1 max_replicas: cluster1: 10 cluster2: 20 diff --git a/prover/crates/bin/prover_autoscaler/src/config.rs b/prover/crates/bin/prover_autoscaler/src/config.rs index 777ffe89fc91..ff3bccf79c83 100644 --- a/prover/crates/bin/prover_autoscaler/src/config.rs +++ b/prover/crates/bin/prover_autoscaler/src/config.rs @@ -59,8 +59,11 @@ pub struct ProverAutoscalerScalerConfig { pub prover_speed: HashMap, /// Maximum number of provers which can be run per cluster/GPU. pub max_provers: HashMap>, - /// Minimum number of provers per namespace. - pub min_provers: HashMap, + /// Minimum number of provers globally. + #[serde(default)] + pub min_provers: u32, + /// Name of primary namespace, all min numbers are applied to it. + pub apply_min_to_namespace: Option, /// Duration after which pending pod considered long pending. #[serde( with = "humantime_serde", @@ -132,6 +135,9 @@ pub enum QueueReportFields { pub struct ScalerTarget { pub queue_report_field: QueueReportFields, pub deployment: String, + /// Min replicas globally. + #[serde(default)] + pub min_replicas: usize, /// Max replicas per cluster. pub max_replicas: HashMap, /// The queue will be divided by the speed and rounded up to get number of replicas. diff --git a/prover/crates/bin/prover_autoscaler/src/global/scaler.rs b/prover/crates/bin/prover_autoscaler/src/global/scaler.rs index 829b95dd7514..074da383b740 100644 --- a/prover/crates/bin/prover_autoscaler/src/global/scaler.rs +++ b/prover/crates/bin/prover_autoscaler/src/global/scaler.rs @@ -73,7 +73,8 @@ pub struct Scaler { pub struct GpuScaler { /// Which cluster to use first. cluster_priorities: HashMap, - min_provers: HashMap, + apply_min_to_namespace: Option, + min_provers: u32, max_provers: HashMap>, prover_speed: HashMap, long_pending_duration: chrono::Duration, @@ -84,6 +85,8 @@ pub struct SimpleScaler { deployment: String, /// Which cluster to use first. cluster_priorities: HashMap, + apply_min_to_namespace: Option, + min_replicas: usize, max_replicas: HashMap, speed: usize, long_pending_duration: chrono::Duration, @@ -126,6 +129,7 @@ impl Scaler { simple_scalers.push(SimpleScaler::new( c, config.cluster_priorities.clone(), + config.apply_min_to_namespace.clone(), chrono::Duration::seconds(config.long_pending_duration.as_secs() as i64), )) } @@ -144,6 +148,7 @@ impl GpuScaler { pub fn new(config: ProverAutoscalerScalerConfig) -> Self { Self { cluster_priorities: config.cluster_priorities, + apply_min_to_namespace: config.apply_min_to_namespace, min_provers: config.min_provers, max_provers: config.max_provers, prover_speed: config.prover_speed, @@ -287,10 +292,12 @@ impl GpuScaler { // Increase queue size, if it's too small, to make sure that required min_provers are // running. - let queue: u64 = self.min_provers.get(namespace).map_or(queue, |min| { + let queue: u64 = if self.apply_min_to_namespace.as_deref() == Some(namespace.as_str()) { self.normalize_queue(Gpu::L4, queue) - .max(self.provers_to_speed(Gpu::L4, *min)) - }); + .max(self.provers_to_speed(Gpu::L4, self.min_provers)) + } else { + queue + }; let mut total: i64 = 0; let mut provers: HashMap = HashMap::new(); @@ -424,12 +431,15 @@ impl SimpleScaler { pub fn new( config: &ScalerTarget, cluster_priorities: HashMap, + apply_min_to_namespace: Option, long_pending_duration: chrono::Duration, ) -> Self { Self { queue_report_field: config.queue_report_field, deployment: config.deployment.clone(), cluster_priorities, + apply_min_to_namespace, + min_replicas: config.min_replicas, max_replicas: config.max_replicas.clone(), speed: config.speed, long_pending_duration, @@ -521,6 +531,15 @@ impl SimpleScaler { &sorted_clusters ); + // Increase queue size, if it's too small, to make sure that required min_provers are + // running. + let queue: u64 = if self.apply_min_to_namespace.as_deref() == Some(namespace.as_str()) { + self.normalize_queue(queue) + .max(self.pods_to_speed(self.min_replicas)) + } else { + queue + }; + let mut total: i64 = 0; let mut pods: HashMap = HashMap::new(); for cluster in &sorted_clusters { @@ -719,7 +738,8 @@ mod tests { fn test_run() { let scaler = GpuScaler::new(ProverAutoscalerScalerConfig { cluster_priorities: [("foo".into(), 0), ("bar".into(), 10)].into(), - min_provers: [("prover-other".into(), 2)].into(), + apply_min_to_namespace: Some("prover-other".into()), + min_provers: 2, max_provers: [ ("foo".into(), [(Gpu::L4, 100)].into()), ("bar".into(), [(Gpu::L4, 100)].into()), @@ -857,7 +877,8 @@ mod tests { fn test_run_min_provers() { let scaler = GpuScaler::new(ProverAutoscalerScalerConfig { cluster_priorities: [("foo".into(), 0), ("bar".into(), 10)].into(), - min_provers: [("prover".into(), 2)].into(), + apply_min_to_namespace: Some("prover".into()), + min_provers: 2, max_provers: [ ("foo".into(), [(Gpu::L4, 100)].into()), ("bar".into(), [(Gpu::L4, 100)].into()), @@ -1052,7 +1073,8 @@ mod tests { fn test_run_need_move() { let scaler = GpuScaler::new(ProverAutoscalerScalerConfig { cluster_priorities: [("foo".into(), 0), ("bar".into(), 10)].into(), - min_provers: [("prover".into(), 2)].into(), + apply_min_to_namespace: Some("prover".into()), + min_provers: 2, max_provers: [ ("foo".into(), [(Gpu::L4, 100)].into()), ("bar".into(), [(Gpu::L4, 100)].into()), diff --git a/prover/docs/.gitignore b/prover/docs/.gitignore new file mode 100644 index 000000000000..7585238efedf --- /dev/null +++ b/prover/docs/.gitignore @@ -0,0 +1 @@ +book diff --git a/prover/docs/99_further_reading.md b/prover/docs/99_further_reading.md deleted file mode 100644 index 64487a715d57..000000000000 --- a/prover/docs/99_further_reading.md +++ /dev/null @@ -1,13 +0,0 @@ -# Further reading - -The documentation in this section aimed to provide a practical overview of the prover workspace, e.g. help people to -understand how to run provers and what they do. - -However, we have some documentation that is more focused on theory of proving in the [core workspace docs](../../docs/). - -You may find the following articles helpful for general understanding of ZK proofs: - -- [ZK intuition](../../docs/guides/advanced/13_zk_intuition.md). -- [ZK deeper overview](../../docs/guides/advanced/14_zk_deeper_overview.md). -- [Prover keys](../../docs/guides/advanced/15_prover_keys.md). -- [Overview of our ZK proving system implementation](../../docs/specs/prover/). diff --git a/prover/docs/book.toml b/prover/docs/book.toml new file mode 100644 index 000000000000..8e0a72942acd --- /dev/null +++ b/prover/docs/book.toml @@ -0,0 +1,32 @@ +[book] +authors = ["ZKsync team"] +language = "en" +multilingual = false +src = "src" +title = "ZKsync Prover Documentation" + +[output.html] +smart-punctuation = true +mathjax-support = true +git-repository-url = "https://github.com/matter-labs/zksync-era/tree/main/prover/docs" +edit-url-template = "https://github.com/matter-labs/zksync-era/tree/main/prover/docs/{path}" +additional-js = ["js/version-box.js", "js/mermaid-init.js"] +additional-css = ["css/version-box.css"] + +[output.html.playground] +editable = true +line-numbers = true + +[output.html.search] +limit-results = 20 +use-boolean-and = true +boost-title = 2 +boost-hierarchy = 2 +boost-paragraph = 1 +expand = true +heading-split-level = 2 + +[preprocessor] + +[preprocessor.mermaid] +command = "mdbook-mermaid" diff --git a/prover/docs/css/version-box.css b/prover/docs/css/version-box.css new file mode 100644 index 000000000000..4006ac7804b3 --- /dev/null +++ b/prover/docs/css/version-box.css @@ -0,0 +1,46 @@ +#version-box { + display: flex; + align-items: center; + margin-right: 15px; /* Space from the right side */ + background-color: transparent; /* Make the box background transparent */ +} + +/* Base styles for the version selector */ +#version-selector { + background-color: transparent; /* Remove background color */ + border: 1px solid #4a5568; /* Subtle border */ + border-radius: 4px; /* Rounded edges */ + padding: 5px 10px; /* Padding inside dropdown */ + font-size: 0.9em; + font-weight: normal; + outline: none; /* Removes default focus outline */ + cursor: pointer; +} + +/* Text color for dark themes */ +.theme-navy #version-selector, +.theme-coal #version-selector { + color: #f7fafc; /* Light text color for dark backgrounds */ +} + +/* Text color for light theme */ +.theme-light #version-selector { + color: #333333; /* Dark text color for light background */ +} + +/* Hover effect for better user feedback */ +#version-selector:hover { + background-color: rgba(255, 255, 255, 0.1); /* Light hover effect */ +} + +/* Optional: Style for when the selector is focused */ +#version-selector:focus { + border-color: #63b3ed; /* Accent color for focused state */ +} + +.right-buttons { + display: flex; + flex-direction: row; /* Aligns items in a row, left to right */ + align-items: center; /* Centers items vertically */ + gap: 10px; /* Adds space between items */ +} diff --git a/prover/docs/js/mermaid-init.js b/prover/docs/js/mermaid-init.js new file mode 100644 index 000000000000..15a7f4e57c60 --- /dev/null +++ b/prover/docs/js/mermaid-init.js @@ -0,0 +1,35 @@ +(() => { + const darkThemes = ['ayu', 'navy', 'coal']; + const lightThemes = ['light', 'rust']; + + const classList = document.getElementsByTagName('html')[0].classList; + + let lastThemeWasLight = true; + for (const cssClass of classList) { + if (darkThemes.includes(cssClass)) { + lastThemeWasLight = false; + break; + } + } + + const theme = lastThemeWasLight ? 'default' : 'dark'; + mermaid.initialize({ startOnLoad: true, theme }); + + // Simplest way to make mermaid re-render the diagrams in the new theme is via refreshing the page + + for (const darkTheme of darkThemes) { + document.getElementById(darkTheme).addEventListener('click', () => { + if (lastThemeWasLight) { + window.location.reload(); + } + }); + } + + for (const lightTheme of lightThemes) { + document.getElementById(lightTheme).addEventListener('click', () => { + if (!lastThemeWasLight) { + window.location.reload(); + } + }); + } +})(); diff --git a/prover/docs/js/version-box.js b/prover/docs/js/version-box.js new file mode 100644 index 000000000000..a7d053e01b47 --- /dev/null +++ b/prover/docs/js/version-box.js @@ -0,0 +1,61 @@ +document.addEventListener('DOMContentLoaded', function () { + // Get the base URL from the mdBook configuration + const baseUrl = document.location.origin + '/zksync-era/prover'; + + // Function to create version selector + function createVersionSelector(versions) { + const versionSelector = document.createElement('select'); + versionSelector.id = 'version-selector'; + + // Get the current path + const currentPath = window.location.pathname; + + // Iterate over the versions object + for (const [versionName, versionUrl] of Object.entries(versions)) { + const option = document.createElement('option'); + option.value = versionUrl + '/'; + option.textContent = versionName; + + // Check if the current URL matches this option's value + if (currentPath.includes(option.value)) { + option.selected = true; // Set this option as selected + } + + versionSelector.appendChild(option); + } + + // Event listener to handle version change + versionSelector.addEventListener('change', function () { + const selectedVersion = versionSelector.value; + // Redirect to the selected version URL + window.location.href = '/zksync-era/prover' + selectedVersion; + }); + + return versionSelector; + } + + // Fetch versions from JSON file + fetch(baseUrl + '/versions.json') + .then((response) => { + if (!response.ok) { + throw new Error('Network response was not ok ' + response.statusText); + } + return response.json(); + }) + .then((data) => { + const versionSelector = createVersionSelector(data); + const nav = document.querySelector('.right-buttons'); + + if (nav) { + const versionBox = document.createElement('div'); + versionBox.id = 'version-box'; + versionBox.appendChild(versionSelector); + nav.appendChild(versionBox); // Append to the .right-buttons container + } else { + console.error('.right-buttons element not found.'); + } + }) + .catch((error) => { + console.error('There has been a problem with your fetch operation:', error); + }); +}); diff --git a/prover/docs/00_intro.md b/prover/docs/src/00_intro.md similarity index 100% rename from prover/docs/00_intro.md rename to prover/docs/src/00_intro.md diff --git a/prover/docs/01_gcp_vm.md b/prover/docs/src/01_gcp_vm.md similarity index 100% rename from prover/docs/01_gcp_vm.md rename to prover/docs/src/01_gcp_vm.md diff --git a/prover/docs/02_setup.md b/prover/docs/src/02_setup.md similarity index 100% rename from prover/docs/02_setup.md rename to prover/docs/src/02_setup.md diff --git a/prover/docs/03_launch.md b/prover/docs/src/03_launch.md similarity index 60% rename from prover/docs/03_launch.md rename to prover/docs/src/03_launch.md index 0465d888f612..fcddf93174b9 100644 --- a/prover/docs/03_launch.md +++ b/prover/docs/src/03_launch.md @@ -2,37 +2,25 @@ ## Preparing -First, run the following command: +First, create a new chain with prover mode `GPU`: -``` -zk env prover-local +```bash +zkstack chain create --prover-mode gpu ``` -It will create a config similar to `dev`, but with: +It will create a config similar to `era`, but with: - Proof sending mode set to `OnlyRealProofs` - Prover mode set to `Local` instead of `GCS`. -You can always switch back to dev config via `zk env dev`. - -**Important:** If you change environments, you have to do `zk init` again. - -## Enter the prover workspace - -All the commands for binaries in the prover workspace must be done from the prover folder: - -``` -cd $ZKSYNC_HOME/prover -``` - ## Key generation This operation should only be done once; if you already generated keys, you can skip it. The following command will generate the required keys: -``` -zk f cargo run --features gpu --release --bin key_generator -- generate-sk-gpu all --recompute-if-missing +```bash +zkstack prover setup-keys ``` With that, you should be ready to run the prover. @@ -40,20 +28,20 @@ With that, you should be ready to run the prover. ## Running Important! Generating a proof takes a lot of time, so if you just want to see whether you can generate a proof, do it -against clean sequencer state (e.g. right after `zk init`). +against clean sequencer state (e.g. right after `zkstack chain init`). We will be running a bunch of binaries, it's recommended to run each in a separate terminal. ### Server -``` -zk server --components=api,tree,eth,state_keeper,housekeeper,commitment_generator,da_dispatcher,proof_data_handler,vm_runner_protective_reads,vm_runner_bwip +```bash +zkstack server --components=api,tree,eth,state_keeper,housekeeper,commitment_generator,da_dispatcher,proof_data_handler,vm_runner_protective_reads,vm_runner_bwip ``` -### Proof data handler +### Prover gateway -``` -zk f cargo run --release --bin zksync_prover_fri_gateway +```bash +zkstack prover run --component=gateway ``` Then wait until the first job is picked up. Prover gateway has to insert protocol information into the database, and @@ -63,8 +51,8 @@ until it happens, witness generators will panic and won't be able to start. Once a job is created, start witness generators: -``` -zk f cargo run --release --bin zksync_witness_generator -- --all_rounds +```bash +zkstack prover run --component=witness-generator --round=all-rounds ``` `--all_rounds` means that witness generator will produce witnesses of all kinds. You can run a witness generator for @@ -72,22 +60,47 @@ each round separately, but it's mostly useful in production environments. ### Witness vector generator -``` -zk f cargo run --release --bin zksync_witness_vector_generator -- --threads 10 +```bash +zkstack prover run --component=witness-vector-generator --threads 10 ``` WVG prepares inputs for prover, and it's a single-threaded time-consuming operation. You may run several jobs by changing the `threads` parameter. The exact amount of WVGs needed to "feed" one prover depends on CPU/GPU specs, but a ballpark estimate (useful for local development) is 10 WVGs per prover. +> NOTE: The WVG thread typically uses approximately 10GB of RAM. + ### Prover -``` -zk f cargo run --features "gpu" --release --bin zksync_prover_fri +```bash +zkstack prover run --component=prover ``` Prover can prove any kinds of circuits, so you only need a single instance. +### Prover job monitor + +You can start the prover job monitor by specifying its component as follows. + +```bash +zkstack prover run --component=prover-job-monitor +``` + +### Insert protocol version in prover database + +Before running the prover, you can insert the protocol version in the prover database by executing the following +command: + +```bash +zkstack dev prover insert-version --version --snark-wrapper= +``` + +To query this information, use the following command: + +```bash +zkstack dev prover info +``` + ### Proof compressor ⚠️ Both prover and proof compressor require 24GB of VRAM, and currently it's not possible to make them use different @@ -96,8 +109,8 @@ GPU. So unless you have a GPU with 48GB of VRAM, you won't be able to run both a You should wait until the proof is generated, and once you see in the server logs that it tries to find available compressor, you can shut the prover down, and run the proof compressor: -``` -zk f cargo run --features "gpu" --release --bin zksync_proof_fri_compressor +```bash +zkstack prover run --component=compressor ``` Once the proof is compressed, proof gateway will see that and will send the generated proof back to core. diff --git a/prover/docs/04_flow.md b/prover/docs/src/04_flow.md similarity index 100% rename from prover/docs/04_flow.md rename to prover/docs/src/04_flow.md diff --git a/prover/docs/05_proving_batch.md b/prover/docs/src/05_proving_batch.md similarity index 100% rename from prover/docs/05_proving_batch.md rename to prover/docs/src/05_proving_batch.md diff --git a/prover/docs/src/99_further_reading.md b/prover/docs/src/99_further_reading.md new file mode 100644 index 000000000000..7b916167dbdd --- /dev/null +++ b/prover/docs/src/99_further_reading.md @@ -0,0 +1,14 @@ +# Further reading + +The documentation in this section aimed to provide a practical overview of the prover workspace, e.g. help people to +understand how to run provers and what they do. + +However, we have some documentation that is more focused on theory of proving in the +[core workspace docs](https://matter-labs.github.io/zksync-era/core/latest). + +You may find the following articles helpful for general understanding of ZK proofs: + +- [ZK intuition](https://matter-labs.github.io/zksync-era/core/latest/guides/advanced/13_zk_intuition.html). +- [ZK deeper overview](https://matter-labs.github.io/zksync-era/core/latest/docs/guides/advanced/14_zk_deeper_overview.html). +- [Prover keys](https://matter-labs.github.io/zksync-era/core/latest/docs/guides/advanced/15_prover_keys.html). +- [Overview of our ZK proving system implementation](https://matter-labs.github.io/zksync-era/core/latest/specs/prover/overview.html). diff --git a/prover/docs/src/README.md b/prover/docs/src/README.md new file mode 100644 index 000000000000..991c91219e99 --- /dev/null +++ b/prover/docs/src/README.md @@ -0,0 +1,16 @@ +# Prover subsystem documentation + +This is technical documentation for the prover subsystem. It aims to help developers to set up a development environment +for working with provers. This documentation assumes that you are already familiar with how ZKsync works, and you need +to be able to work with the prover code. + +It does not cover topics such as basics of ZK or production deployment for provers. + +## Table of contents + +- [Intro](00_intro.md) +- [Setting up a GCP VM](01_gcp_vm.md) +- [Workspace setup](02_setup.md) +- [Running prover subsystem](03_launch.md) +- [Proof generation flow](04_flow.md) +- [Further reading](99_further_reading.md) diff --git a/prover/docs/src/SUMMARY.md b/prover/docs/src/SUMMARY.md new file mode 100644 index 000000000000..d4a6fa15d778 --- /dev/null +++ b/prover/docs/src/SUMMARY.md @@ -0,0 +1,11 @@ +# Summary + +[Introduction](./00_intro.md) + +- [Creating a GCP VM](./01_gcp_vm.md) +- [Development environment setup](./02_setup.md) +- [Running provers](./03_launch.md) +- [Prover flow](./04_flow.md) +- [Proving a batch](./05_proving_batch.md) + +[Further reading](./99_further_reading.md) diff --git a/prover/docs/theme/head.hbs b/prover/docs/theme/head.hbs new file mode 100644 index 000000000000..66ee37538adf --- /dev/null +++ b/prover/docs/theme/head.hbs @@ -0,0 +1 @@ + diff --git a/zkstack_cli/Cargo.lock b/zkstack_cli/Cargo.lock index a582fff958f5..2206a1052f59 100644 --- a/zkstack_cli/Cargo.lock +++ b/zkstack_cli/Cargo.lock @@ -297,12 +297,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - [[package]] name = "base16ct" version = "0.2.0" @@ -659,7 +653,7 @@ dependencies = [ "coins-core", "digest", "hmac", - "k256 0.13.4", + "k256", "serde", "sha2", "thiserror", @@ -938,18 +932,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - [[package]] name = "crypto-bigint" version = "0.5.5" @@ -1069,16 +1051,6 @@ dependencies = [ "uuid 1.10.0", ] -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - [[package]] name = "der" version = "0.7.9" @@ -1221,30 +1193,18 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - [[package]] name = "ecdsa" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.9", + "der", "digest", - "elliptic-curve 0.13.8", - "rfc6979 0.4.0", - "signature 2.2.0", - "spki 0.7.3", + "elliptic-curve", + "rfc6979", + "signature", + "spki", ] [[package]] @@ -1253,8 +1213,8 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8 0.10.2", - "signature 2.2.0", + "pkcs8", + "signature", ] [[package]] @@ -1281,41 +1241,21 @@ dependencies = [ "serde", ] -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest", - "ff 0.12.1", - "generic-array", - "group 0.12.1", - "pkcs8 0.9.0", - "rand_core", - "sec1 0.3.0", - "subtle", - "zeroize", -] - [[package]] name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.5", + "base16ct", + "crypto-bigint", "digest", - "ff 0.13.0", + "ff", "generic-array", - "group 0.13.0", - "pkcs8 0.10.2", + "group", + "pkcs8", "rand_core", - "sec1 0.7.3", + "sec1", "subtle", "zeroize", ] @@ -1362,7 +1302,7 @@ dependencies = [ "base64 0.21.7", "bytes", "hex", - "k256 0.13.4", + "k256", "log", "rand", "rlp", @@ -1587,11 +1527,11 @@ dependencies = [ "cargo_metadata", "chrono", "const-hex", - "elliptic-curve 0.13.8", + "elliptic-curve", "ethabi", "generic-array", - "k256 0.13.4", - "num_enum 0.7.3", + "k256", + "num_enum", "once_cell", "open-fastrlp", "rand", @@ -1696,7 +1636,7 @@ dependencies = [ "coins-bip32", "coins-bip39", "const-hex", - "elliptic-curve 0.13.8", + "elliptic-curve", "eth-keystore", "ethers-core", "rand", @@ -1775,16 +1715,6 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core", - "subtle", -] - [[package]] name = "ff" version = "0.13.0" @@ -2082,24 +2012,13 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core", - "subtle", -] - [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff", "rand_core", "subtle", ] @@ -2679,18 +2598,6 @@ dependencies = [ "simple_asn1", ] -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2", -] - [[package]] name = "k256" version = "0.13.4" @@ -2698,11 +2605,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", + "ecdsa", + "elliptic-curve", "once_cell", "sha2", - "signature 2.2.0", + "signature", ] [[package]] @@ -3130,34 +3037,13 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", -] - [[package]] name = "num_enum" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ - "num_enum_derive 0.7.3", -] - -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 2.0.79", + "num_enum_derive", ] [[package]] @@ -3166,7 +3052,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.79", @@ -3412,7 +3298,7 @@ version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -3627,19 +3513,9 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der 0.7.9", - "pkcs8 0.10.2", - "spki 0.7.3", -] - -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", + "der", + "pkcs8", + "spki", ] [[package]] @@ -3648,8 +3524,8 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.9", - "spki 0.7.3", + "der", + "spki", ] [[package]] @@ -3719,23 +3595,13 @@ dependencies = [ "uint", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.22.22", + "toml_edit", ] [[package]] @@ -4140,17 +4006,6 @@ dependencies = [ "windows-registry", ] -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac", - "zeroize", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -4234,10 +4089,10 @@ dependencies = [ "num-integer", "num-traits", "pkcs1", - "pkcs8 0.10.2", + "pkcs8", "rand_core", - "signature 2.2.0", - "spki 0.7.3", + "signature", + "spki", "subtle", "zeroize", ] @@ -4400,7 +4255,7 @@ version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -4443,30 +4298,16 @@ dependencies = [ "untrusted 0.9.0", ] -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array", - "pkcs8 0.9.0", - "subtle", - "zeroize", -] - [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct 0.2.0", - "der 0.7.9", + "base16ct", + "der", "generic-array", - "pkcs8 0.10.2", + "pkcs8", "subtle", "zeroize", ] @@ -4771,17 +4612,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha2_ce" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca2daa77078f4ddff27e75c4bf59e4c2697525f56dbb3c842d34a5d1f2b04a2" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "sha3" version = "0.10.8" @@ -4792,16 +4622,6 @@ dependencies = [ "keccak", ] -[[package]] -name = "sha3_ce" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34c9a08202c50378d8a07a5f458193a5f542d2828ac6640263dbc0c2533ea25e" -dependencies = [ - "digest", - "keccak", -] - [[package]] name = "sharded-slab" version = "0.1.7" @@ -4826,16 +4646,6 @@ dependencies = [ "libc", ] -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest", - "rand_core", -] - [[package]] name = "signature" version = "2.2.0" @@ -4953,16 +4763,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - [[package]] name = "spki" version = "0.7.3" @@ -4970,7 +4770,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.9", + "der", ] [[package]] @@ -5700,7 +5500,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.22", + "toml_edit", ] [[package]] @@ -5712,17 +5512,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.6.0", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.22" @@ -5733,7 +5522,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.20", + "winnow", ] [[package]] @@ -6530,15 +6319,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.20" @@ -6674,50 +6454,6 @@ dependencies = [ "zstd", ] -[[package]] -name = "zk_evm" -version = "0.133.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af08e9284686a1b0c89ec4931eb915ac0729367f1247abd06164874fe738106" -dependencies = [ - "anyhow", - "lazy_static", - "num", - "serde", - "serde_json", - "static_assertions", - "zk_evm_abstractions", - "zkevm_opcode_defs", -] - -[[package]] -name = "zk_evm_abstractions" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be696258861eba4e6625a5665084b2266720bb67f4ba69819469700ac5c6a401" -dependencies = [ - "anyhow", - "num_enum 0.6.1", - "serde", - "static_assertions", - "zkevm_opcode_defs", -] - -[[package]] -name = "zkevm_opcode_defs" -version = "0.132.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0769f7b27d8fb06e715da3290c575cac5d04d10a557faef180e847afce50ac4" -dependencies = [ - "bitflags 2.6.0", - "blake2", - "ethereum-types", - "k256 0.11.6", - "lazy_static", - "sha2_ce", - "sha3_ce", -] - [[package]] name = "zkstack" version = "0.1.0" @@ -6767,13 +6503,15 @@ version = "0.1.0" dependencies = [ "anyhow", "chrono", + "const-decoder", "ethabi", "hex", - "num_enum 0.7.3", + "num_enum", "secrecy", "serde", "serde_json", "serde_with", + "sha2", "strum", "thiserror", "tiny-keccak", @@ -6822,9 +6560,9 @@ dependencies = [ "anyhow", "blst", "ed25519-dalek", - "elliptic-curve 0.13.8", + "elliptic-curve", "hex", - "k256 0.13.4", + "k256", "num-bigint", "num-traits", "rand", @@ -6873,11 +6611,11 @@ name = "zksync_contracts" version = "0.1.0" dependencies = [ "envy", - "ethabi", "hex", "once_cell", "serde", "serde_json", + "zksync_basic_types", "zksync_utils", ] @@ -6983,7 +6721,7 @@ dependencies = [ "hex", "itertools 0.10.5", "num", - "num_enum 0.7.3", + "num_enum", "once_cell", "prost 0.12.6", "rlp", @@ -7000,7 +6738,6 @@ dependencies = [ "zksync_protobuf", "zksync_protobuf_build", "zksync_system_constants", - "zksync_utils", ] [[package]] @@ -7008,16 +6745,12 @@ name = "zksync_utils" version = "0.1.0" dependencies = [ "anyhow", - "const-decoder", "futures", "once_cell", "reqwest 0.12.8", "serde_json", - "thiserror", "tokio", "tracing", - "zk_evm", - "zksync_basic_types", "zksync_vlog", ] diff --git a/zkstack_cli/crates/zkstack/completion/_zkstack.zsh b/zkstack_cli/crates/zkstack/completion/_zkstack.zsh index d9977d574816..f0e10b465b6a 100644 --- a/zkstack_cli/crates/zkstack/completion/_zkstack.zsh +++ b/zkstack_cli/crates/zkstack/completion/_zkstack.zsh @@ -2008,15 +2008,96 @@ _arguments "${_arguments_options[@]}" : \ '*--additional-args=[Additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS:_default' \ '--chain=[Chain to use]:CHAIN:_default' \ '--genesis[Run server in genesis mode]' \ -'--build[Build server but don'\''t run it]' \ '--uring[Enables uring support for RocksDB]' \ '-v[Verbose mode]' \ '--verbose[Verbose mode]' \ '--ignore-prerequisites[Ignores prerequisites checks]' \ '-h[Print help]' \ '--help[Print help]' \ +":: :_zkstack__server_commands" \ +"*::: :->server" \ +&& ret=0 + + case $state in + (server) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-server-command-$line[1]:" + case $line[1] in + (build) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN:_default' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +'*--components=[Components of server to run]:COMPONENTS:_default' \ +'*-a+[Additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS:_default' \ +'*--additional-args=[Additional arguments that can be passed through the CLI]:ADDITIONAL_ARGS:_default' \ +'--chain=[Chain to use]:CHAIN:_default' \ +'--genesis[Run server in genesis mode]' \ +'--uring[Enables uring support for RocksDB]' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(wait) +_arguments "${_arguments_options[@]}" : \ +'-t+[Wait timeout in seconds]:SECONDS:_default' \ +'--timeout=[Wait timeout in seconds]:SECONDS:_default' \ +'--poll-interval=[Poll interval in milliseconds]:MILLIS:_default' \ +'--chain=[Chain to use]:CHAIN:_default' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ && ret=0 ;; +(help) +_arguments "${_arguments_options[@]}" : \ +":: :_zkstack__server__help_commands" \ +"*::: :->help" \ +&& ret=0 + + case $state in + (help) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-server-help-command-$line[1]:" + case $line[1] in + (build) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(wait) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; + esac + ;; +esac +;; (external-node) _arguments "${_arguments_options[@]}" : \ '--chain=[Chain to use]:CHAIN:_default' \ @@ -2060,6 +2141,16 @@ _arguments "${_arguments_options[@]}" : \ '--help[Print help]' \ && ret=0 ;; +(build) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN:_default' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; (run) _arguments "${_arguments_options[@]}" : \ '*--components=[Components of server to run]:COMPONENTS:_default' \ @@ -2075,6 +2166,19 @@ _arguments "${_arguments_options[@]}" : \ '--help[Print help]' \ && ret=0 ;; +(wait) +_arguments "${_arguments_options[@]}" : \ +'-t+[Wait timeout in seconds]:SECONDS:_default' \ +'--timeout=[Wait timeout in seconds]:SECONDS:_default' \ +'--poll-interval=[Poll interval in milliseconds]:MILLIS:_default' \ +'--chain=[Chain to use]:CHAIN:_default' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ ":: :_zkstack__external-node__help_commands" \ @@ -2095,10 +2199,18 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(build) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; (run) _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(wait) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ && ret=0 @@ -2141,8 +2253,31 @@ _arguments "${_arguments_options[@]}" : \ (( CURRENT += 1 )) curcontext="${curcontext%:*:*}:zkstack-contract-verifier-command-$line[1]:" case $line[1] in - (run) + (build) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN:_default' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +'--chain=[Chain to use]:CHAIN:_default' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(wait) _arguments "${_arguments_options[@]}" : \ +'-t+[Wait timeout in seconds]:SECONDS:_default' \ +'--timeout=[Wait timeout in seconds]:SECONDS:_default' \ +'--poll-interval=[Poll interval in milliseconds]:MILLIS:_default' \ '--chain=[Chain to use]:CHAIN:_default' \ '-v[Verbose mode]' \ '--verbose[Verbose mode]' \ @@ -2179,7 +2314,15 @@ _arguments "${_arguments_options[@]}" : \ (( CURRENT += 1 )) curcontext="${curcontext%:*:*}:zkstack-contract-verifier-help-command-$line[1]:" case $line[1] in - (run) + (build) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(wait) _arguments "${_arguments_options[@]}" : \ && ret=0 ;; @@ -2333,6 +2476,19 @@ _arguments "${_arguments_options[@]}" : \ '--help[Print help]' \ && ret=0 ;; +(wait-for-registry) +_arguments "${_arguments_options[@]}" : \ +'-t+[Wait timeout in seconds]:SECONDS:_default' \ +'--timeout=[Wait timeout in seconds]:SECONDS:_default' \ +'--poll-interval=[Poll interval in milliseconds]:MILLIS:_default' \ +'--chain=[Chain to use]:CHAIN:_default' \ +'-v[Verbose mode]' \ +'--verbose[Verbose mode]' \ +'--ignore-prerequisites[Ignores prerequisites checks]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ ":: :_zkstack__consensus__help_commands" \ @@ -2353,6 +2509,10 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(wait-for-registry) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ && ret=0 @@ -2849,8 +3009,32 @@ esac ;; (server) _arguments "${_arguments_options[@]}" : \ +":: :_zkstack__help__server_commands" \ +"*::: :->server" \ +&& ret=0 + + case $state in + (server) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zkstack-help-server-command-$line[1]:" + case $line[1] in + (build) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(wait) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; + esac + ;; +esac +;; (external-node) _arguments "${_arguments_options[@]}" : \ ":: :_zkstack__help__external-node_commands" \ @@ -2871,9 +3055,17 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(build) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; (run) _arguments "${_arguments_options[@]}" : \ && ret=0 +;; +(wait) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 ;; esac ;; @@ -2895,7 +3087,15 @@ _arguments "${_arguments_options[@]}" : \ (( CURRENT += 1 )) curcontext="${curcontext%:*:*}:zkstack-help-contract-verifier-command-$line[1]:" case $line[1] in - (run) + (build) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(run) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(wait) _arguments "${_arguments_options[@]}" : \ && ret=0 ;; @@ -2958,6 +3158,10 @@ _arguments "${_arguments_options[@]}" : \ (get-attester-committee) _arguments "${_arguments_options[@]}" : \ && ret=0 +;; +(wait-for-registry) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 ;; esac ;; @@ -3286,6 +3490,7 @@ _zkstack__consensus_commands() { local commands; commands=( 'set-attester-committee:Sets the attester committee in the consensus registry contract to \`consensus.genesis_spec.attesters\` in general.yaml' \ 'get-attester-committee:Fetches the attester committee from the consensus registry contract' \ +'wait-for-registry:Wait until the consensus registry contract is deployed to L2' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'zkstack consensus commands' commands "$@" @@ -3300,6 +3505,7 @@ _zkstack__consensus__help_commands() { local commands; commands=( 'set-attester-committee:Sets the attester committee in the consensus registry contract to \`consensus.genesis_spec.attesters\` in general.yaml' \ 'get-attester-committee:Fetches the attester committee from the consensus registry contract' \ +'wait-for-registry:Wait until the consensus registry contract is deployed to L2' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'zkstack consensus help commands' commands "$@" @@ -3319,11 +3525,21 @@ _zkstack__consensus__help__set-attester-committee_commands() { local commands; commands=() _describe -t commands 'zkstack consensus help set-attester-committee commands' commands "$@" } +(( $+functions[_zkstack__consensus__help__wait-for-registry_commands] )) || +_zkstack__consensus__help__wait-for-registry_commands() { + local commands; commands=() + _describe -t commands 'zkstack consensus help wait-for-registry commands' commands "$@" +} (( $+functions[_zkstack__consensus__set-attester-committee_commands] )) || _zkstack__consensus__set-attester-committee_commands() { local commands; commands=() _describe -t commands 'zkstack consensus set-attester-committee commands' commands "$@" } +(( $+functions[_zkstack__consensus__wait-for-registry_commands] )) || +_zkstack__consensus__wait-for-registry_commands() { + local commands; commands=() + _describe -t commands 'zkstack consensus wait-for-registry commands' commands "$@" +} (( $+functions[_zkstack__containers_commands] )) || _zkstack__containers_commands() { local commands; commands=() @@ -3332,21 +3548,35 @@ _zkstack__containers_commands() { (( $+functions[_zkstack__contract-verifier_commands] )) || _zkstack__contract-verifier_commands() { local commands; commands=( +'build:Build contract verifier binary' \ 'run:Run contract verifier' \ +'wait:Wait for contract verifier to start' \ 'init:Download required binaries for contract verifier' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'zkstack contract-verifier commands' commands "$@" } +(( $+functions[_zkstack__contract-verifier__build_commands] )) || +_zkstack__contract-verifier__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack contract-verifier build commands' commands "$@" +} (( $+functions[_zkstack__contract-verifier__help_commands] )) || _zkstack__contract-verifier__help_commands() { local commands; commands=( +'build:Build contract verifier binary' \ 'run:Run contract verifier' \ +'wait:Wait for contract verifier to start' \ 'init:Download required binaries for contract verifier' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'zkstack contract-verifier help commands' commands "$@" } +(( $+functions[_zkstack__contract-verifier__help__build_commands] )) || +_zkstack__contract-verifier__help__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack contract-verifier help build commands' commands "$@" +} (( $+functions[_zkstack__contract-verifier__help__help_commands] )) || _zkstack__contract-verifier__help__help_commands() { local commands; commands=() @@ -3362,6 +3592,11 @@ _zkstack__contract-verifier__help__run_commands() { local commands; commands=() _describe -t commands 'zkstack contract-verifier help run commands' commands "$@" } +(( $+functions[_zkstack__contract-verifier__help__wait_commands] )) || +_zkstack__contract-verifier__help__wait_commands() { + local commands; commands=() + _describe -t commands 'zkstack contract-verifier help wait commands' commands "$@" +} (( $+functions[_zkstack__contract-verifier__init_commands] )) || _zkstack__contract-verifier__init_commands() { local commands; commands=() @@ -3372,6 +3607,11 @@ _zkstack__contract-verifier__run_commands() { local commands; commands=() _describe -t commands 'zkstack contract-verifier run commands' commands "$@" } +(( $+functions[_zkstack__contract-verifier__wait_commands] )) || +_zkstack__contract-verifier__wait_commands() { + local commands; commands=() + _describe -t commands 'zkstack contract-verifier wait commands' commands "$@" +} (( $+functions[_zkstack__dev_commands] )) || _zkstack__dev_commands() { local commands; commands=( @@ -4301,11 +4541,18 @@ _zkstack__external-node_commands() { local commands; commands=( 'configs:Prepare configs for EN' \ 'init:Init databases' \ +'build:Build external node' \ 'run:Run external node' \ +'wait:Wait for external node to start' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'zkstack external-node commands' commands "$@" } +(( $+functions[_zkstack__external-node__build_commands] )) || +_zkstack__external-node__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node build commands' commands "$@" +} (( $+functions[_zkstack__external-node__configs_commands] )) || _zkstack__external-node__configs_commands() { local commands; commands=() @@ -4316,11 +4563,18 @@ _zkstack__external-node__help_commands() { local commands; commands=( 'configs:Prepare configs for EN' \ 'init:Init databases' \ +'build:Build external node' \ 'run:Run external node' \ +'wait:Wait for external node to start' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'zkstack external-node help commands' commands "$@" } +(( $+functions[_zkstack__external-node__help__build_commands] )) || +_zkstack__external-node__help__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node help build commands' commands "$@" +} (( $+functions[_zkstack__external-node__help__configs_commands] )) || _zkstack__external-node__help__configs_commands() { local commands; commands=() @@ -4341,6 +4595,11 @@ _zkstack__external-node__help__run_commands() { local commands; commands=() _describe -t commands 'zkstack external-node help run commands' commands "$@" } +(( $+functions[_zkstack__external-node__help__wait_commands] )) || +_zkstack__external-node__help__wait_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node help wait commands' commands "$@" +} (( $+functions[_zkstack__external-node__init_commands] )) || _zkstack__external-node__init_commands() { local commands; commands=() @@ -4351,6 +4610,11 @@ _zkstack__external-node__run_commands() { local commands; commands=() _describe -t commands 'zkstack external-node run commands' commands "$@" } +(( $+functions[_zkstack__external-node__wait_commands] )) || +_zkstack__external-node__wait_commands() { + local commands; commands=() + _describe -t commands 'zkstack external-node wait commands' commands "$@" +} (( $+functions[_zkstack__help_commands] )) || _zkstack__help_commands() { local commands; commands=( @@ -4492,6 +4756,7 @@ _zkstack__help__consensus_commands() { local commands; commands=( 'set-attester-committee:Sets the attester committee in the consensus registry contract to \`consensus.genesis_spec.attesters\` in general.yaml' \ 'get-attester-committee:Fetches the attester committee from the consensus registry contract' \ +'wait-for-registry:Wait until the consensus registry contract is deployed to L2' \ ) _describe -t commands 'zkstack help consensus commands' commands "$@" } @@ -4505,6 +4770,11 @@ _zkstack__help__consensus__set-attester-committee_commands() { local commands; commands=() _describe -t commands 'zkstack help consensus set-attester-committee commands' commands "$@" } +(( $+functions[_zkstack__help__consensus__wait-for-registry_commands] )) || +_zkstack__help__consensus__wait-for-registry_commands() { + local commands; commands=() + _describe -t commands 'zkstack help consensus wait-for-registry commands' commands "$@" +} (( $+functions[_zkstack__help__containers_commands] )) || _zkstack__help__containers_commands() { local commands; commands=() @@ -4513,11 +4783,18 @@ _zkstack__help__containers_commands() { (( $+functions[_zkstack__help__contract-verifier_commands] )) || _zkstack__help__contract-verifier_commands() { local commands; commands=( +'build:Build contract verifier binary' \ 'run:Run contract verifier' \ +'wait:Wait for contract verifier to start' \ 'init:Download required binaries for contract verifier' \ ) _describe -t commands 'zkstack help contract-verifier commands' commands "$@" } +(( $+functions[_zkstack__help__contract-verifier__build_commands] )) || +_zkstack__help__contract-verifier__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack help contract-verifier build commands' commands "$@" +} (( $+functions[_zkstack__help__contract-verifier__init_commands] )) || _zkstack__help__contract-verifier__init_commands() { local commands; commands=() @@ -4528,6 +4805,11 @@ _zkstack__help__contract-verifier__run_commands() { local commands; commands=() _describe -t commands 'zkstack help contract-verifier run commands' commands "$@" } +(( $+functions[_zkstack__help__contract-verifier__wait_commands] )) || +_zkstack__help__contract-verifier__wait_commands() { + local commands; commands=() + _describe -t commands 'zkstack help contract-verifier wait commands' commands "$@" +} (( $+functions[_zkstack__help__dev_commands] )) || _zkstack__help__dev_commands() { local commands; commands=( @@ -4852,10 +5134,17 @@ _zkstack__help__external-node_commands() { local commands; commands=( 'configs:Prepare configs for EN' \ 'init:Init databases' \ +'build:Build external node' \ 'run:Run external node' \ +'wait:Wait for external node to start' \ ) _describe -t commands 'zkstack help external-node commands' commands "$@" } +(( $+functions[_zkstack__help__external-node__build_commands] )) || +_zkstack__help__external-node__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack help external-node build commands' commands "$@" +} (( $+functions[_zkstack__help__external-node__configs_commands] )) || _zkstack__help__external-node__configs_commands() { local commands; commands=() @@ -4871,6 +5160,11 @@ _zkstack__help__external-node__run_commands() { local commands; commands=() _describe -t commands 'zkstack help external-node run commands' commands "$@" } +(( $+functions[_zkstack__help__external-node__wait_commands] )) || +_zkstack__help__external-node__wait_commands() { + local commands; commands=() + _describe -t commands 'zkstack help external-node wait commands' commands "$@" +} (( $+functions[_zkstack__help__help_commands] )) || _zkstack__help__help_commands() { local commands; commands=() @@ -4924,9 +5218,28 @@ _zkstack__help__prover__setup-keys_commands() { } (( $+functions[_zkstack__help__server_commands] )) || _zkstack__help__server_commands() { - local commands; commands=() + local commands; commands=( +'build:Builds server' \ +'run:Runs server' \ +'wait:Waits for server to start' \ + ) _describe -t commands 'zkstack help server commands' commands "$@" } +(( $+functions[_zkstack__help__server__build_commands] )) || +_zkstack__help__server__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack help server build commands' commands "$@" +} +(( $+functions[_zkstack__help__server__run_commands] )) || +_zkstack__help__server__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack help server run commands' commands "$@" +} +(( $+functions[_zkstack__help__server__wait_commands] )) || +_zkstack__help__server__wait_commands() { + local commands; commands=() + _describe -t commands 'zkstack help server wait commands' commands "$@" +} (( $+functions[_zkstack__help__update_commands] )) || _zkstack__help__update_commands() { local commands; commands=() @@ -5023,9 +5336,59 @@ _zkstack__prover__setup-keys_commands() { } (( $+functions[_zkstack__server_commands] )) || _zkstack__server_commands() { - local commands; commands=() + local commands; commands=( +'build:Builds server' \ +'run:Runs server' \ +'wait:Waits for server to start' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) _describe -t commands 'zkstack server commands' commands "$@" } +(( $+functions[_zkstack__server__build_commands] )) || +_zkstack__server__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack server build commands' commands "$@" +} +(( $+functions[_zkstack__server__help_commands] )) || +_zkstack__server__help_commands() { + local commands; commands=( +'build:Builds server' \ +'run:Runs server' \ +'wait:Waits for server to start' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'zkstack server help commands' commands "$@" +} +(( $+functions[_zkstack__server__help__build_commands] )) || +_zkstack__server__help__build_commands() { + local commands; commands=() + _describe -t commands 'zkstack server help build commands' commands "$@" +} +(( $+functions[_zkstack__server__help__help_commands] )) || +_zkstack__server__help__help_commands() { + local commands; commands=() + _describe -t commands 'zkstack server help help commands' commands "$@" +} +(( $+functions[_zkstack__server__help__run_commands] )) || +_zkstack__server__help__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack server help run commands' commands "$@" +} +(( $+functions[_zkstack__server__help__wait_commands] )) || +_zkstack__server__help__wait_commands() { + local commands; commands=() + _describe -t commands 'zkstack server help wait commands' commands "$@" +} +(( $+functions[_zkstack__server__run_commands] )) || +_zkstack__server__run_commands() { + local commands; commands=() + _describe -t commands 'zkstack server run commands' commands "$@" +} +(( $+functions[_zkstack__server__wait_commands] )) || +_zkstack__server__wait_commands() { + local commands; commands=() + _describe -t commands 'zkstack server wait commands' commands "$@" +} (( $+functions[_zkstack__update_commands] )) || _zkstack__update_commands() { local commands; commands=() diff --git a/zkstack_cli/crates/zkstack/completion/zkstack.fish b/zkstack_cli/crates/zkstack/completion/zkstack.fish index be6d5d147e78..dacc27d88089 100644 --- a/zkstack_cli/crates/zkstack/completion/zkstack.fish +++ b/zkstack_cli/crates/zkstack/completion/zkstack.fish @@ -525,23 +525,50 @@ 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 help" -f -a "init-bellman-cuda" -d 'Initialize bellman-cuda' complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from help" -f -a "compressor-keys" -d 'Download compressor keys' complete -c zkstack -n "__fish_zkstack_using_subcommand prover; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l components -d 'Components of server to run' -r -complete -c zkstack -n "__fish_zkstack_using_subcommand server" -s a -l additional-args -d 'Additional arguments that can be passed through the CLI' -r -complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l chain -d 'Chain to use' -r -complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l genesis -d 'Run server in genesis mode' -complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l build -d 'Build server but don\'t run it' -complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l uring -d 'Enables uring support for RocksDB' -complete -c zkstack -n "__fish_zkstack_using_subcommand server" -s v -l verbose -d 'Verbose mode' -complete -c zkstack -n "__fish_zkstack_using_subcommand server" -l ignore-prerequisites -d 'Ignores prerequisites checks' -complete -c zkstack -n "__fish_zkstack_using_subcommand server" -s h -l help -d 'Print help' -complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -l chain -d 'Chain to use' -r -complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -s v -l verbose -d 'Verbose mode' -complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -l ignore-prerequisites -d 'Ignores prerequisites checks' -complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -s h -l help -d 'Print help' -complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -f -a "configs" -d 'Prepare configs for EN' -complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -f -a "init" -d 'Init databases' -complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -f -a "run" -d 'Run external node' -complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init run help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -l components -d 'Components of server to run' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -s a -l additional-args -d 'Additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -l genesis -d 'Run server in genesis mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -l uring -d 'Enables uring support for RocksDB' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -f -a "build" -d 'Builds server' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -f -a "run" -d 'Runs server' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -f -a "wait" -d 'Waits for server to start' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and not __fish_seen_subcommand_from build run wait help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from build" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from build" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from build" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from build" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from run" -l components -d 'Components of server to run' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from run" -s a -l additional-args -d 'Additional arguments that can be passed through the CLI' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from run" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from run" -l genesis -d 'Run server in genesis mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from run" -l uring -d 'Enables uring support for RocksDB' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from run" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from run" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from run" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from wait" -s t -l timeout -d 'Wait timeout in seconds' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from wait" -l poll-interval -d 'Poll interval in milliseconds' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from wait" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from wait" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from wait" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from wait" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from help" -f -a "build" -d 'Builds server' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from help" -f -a "run" -d 'Runs server' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from help" -f -a "wait" -d 'Waits for server to start' +complete -c zkstack -n "__fish_zkstack_using_subcommand server; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -f -a "configs" -d 'Prepare configs for EN' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -f -a "init" -d 'Init databases' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -f -a "build" -d 'Build external node' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -f -a "run" -d 'Run external node' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -f -a "wait" -d 'Wait for external node to start' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and not __fish_seen_subcommand_from configs init build run wait help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -l db-url -r complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -l db-name -r complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from configs" -l l1-rpc-url -r @@ -554,6 +581,10 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fis complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from init" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from build" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from build" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from build" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from build" -s h -l help -d 'Print help' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -l components -d 'Components of server to run' -r complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -l enable-consensus -d 'Enable consensus' -r -f -a "{true\t'',false\t''}" complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -s a -l additional-args -d 'Additional arguments that can be passed through the CLI' -r @@ -562,26 +593,46 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fis complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -l ignore-prerequisites -d 'Ignores prerequisites checks' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from run" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from wait" -s t -l timeout -d 'Wait timeout in seconds' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from wait" -l poll-interval -d 'Poll interval in milliseconds' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from wait" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from wait" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from wait" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from wait" -s h -l help -d 'Print help' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "configs" -d 'Prepare configs for EN' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "init" -d 'Init databases' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "build" -d 'Build external node' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "run" -d 'Run external node' +complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "wait" -d 'Wait for external node to start' complete -c zkstack -n "__fish_zkstack_using_subcommand external-node; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -s o -l observability -d 'Enable Grafana' -r -f -a "{true\t'',false\t''}" complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -l chain -d 'Chain to use' -r complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -l ignore-prerequisites -d 'Ignores prerequisites checks' complete -c zkstack -n "__fish_zkstack_using_subcommand containers" -s h -l help -d 'Print help' -complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -l chain -d 'Chain to use' -r -complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -s v -l verbose -d 'Verbose mode' -complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -l ignore-prerequisites -d 'Ignores prerequisites checks' -complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -s h -l help -d 'Print help' -complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -f -a "run" -d 'Run contract verifier' -complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -f -a "init" -d 'Download required binaries for contract verifier' -complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from run init help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from build run wait init help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from build run wait init help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from build run wait init help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from build run wait init help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from build run wait init help" -f -a "build" -d 'Build contract verifier binary' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from build run wait init help" -f -a "run" -d 'Run contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from build run wait init help" -f -a "wait" -d 'Wait for contract verifier to start' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from build run wait init help" -f -a "init" -d 'Download required binaries for contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and not __fish_seen_subcommand_from build run wait init help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from build" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from build" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from build" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from build" -s h -l help -d 'Print help' complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from run" -l chain -d 'Chain to use' -r complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from run" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from run" -l ignore-prerequisites -d 'Ignores prerequisites checks' complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from run" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from wait" -s t -l timeout -d 'Wait timeout in seconds' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from wait" -l poll-interval -d 'Poll interval in milliseconds' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from wait" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from wait" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from wait" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from wait" -s h -l help -d 'Print help' complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l zksolc-version -d 'Version of zksolc to install' -r complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l zkvyper-version -d 'Version of zkvyper to install' -r complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l solc-version -d 'Version of solc to install' -r @@ -592,7 +643,9 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and _ complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -l ignore-prerequisites -d 'Ignores prerequisites checks' complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from init" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from help" -f -a "build" -d 'Build contract verifier binary' complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from help" -f -a "run" -d 'Run contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from help" -f -a "wait" -d 'Wait for contract verifier to start' complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from help" -f -a "init" -d 'Download required binaries for contract verifier' complete -c zkstack -n "__fish_zkstack_using_subcommand contract-verifier; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c zkstack -n "__fish_zkstack_using_subcommand portal" -l chain -d 'Chain to use' -r @@ -623,13 +676,14 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_see complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from help" -f -a "run-backend" -d 'Start explorer backend services (api, data_fetcher, worker) for a given chain. Uses default chain, unless --chain is passed' complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from help" -f -a "run" -d 'Run explorer app' complete -c zkstack -n "__fish_zkstack_using_subcommand explorer; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -l chain -d 'Chain to use' -r -complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -s v -l verbose -d 'Verbose mode' -complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -l ignore-prerequisites -d 'Ignores prerequisites checks' -complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -s h -l help -d 'Print help' -complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -f -a "set-attester-committee" -d 'Sets the attester committee in the consensus registry contract to `consensus.genesis_spec.attesters` in general.yaml' -complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -f -a "get-attester-committee" -d 'Fetches the attester committee from the consensus registry contract' -complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee wait-for-registry help" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee wait-for-registry help" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee wait-for-registry help" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee wait-for-registry help" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee wait-for-registry help" -f -a "set-attester-committee" -d 'Sets the attester committee in the consensus registry contract to `consensus.genesis_spec.attesters` in general.yaml' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee wait-for-registry help" -f -a "get-attester-committee" -d 'Fetches the attester committee from the consensus registry contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee wait-for-registry help" -f -a "wait-for-registry" -d 'Wait until the consensus registry contract is deployed to L2' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and not __fish_seen_subcommand_from set-attester-committee get-attester-committee wait-for-registry help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from set-attester-committee" -l from-file -d 'Sets the attester committee in the consensus registry contract to the committee in the yaml file. File format is definied in `commands/consensus/proto/mod.proto`' -r -F complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from set-attester-committee" -l chain -d 'Chain to use' -r complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from set-attester-committee" -l from-genesis -d 'Sets the attester committee in the consensus registry contract to `consensus.genesis_spec.attesters` in general.yaml' @@ -640,8 +694,15 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_se complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from get-attester-committee" -s v -l verbose -d 'Verbose mode' complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from get-attester-committee" -l ignore-prerequisites -d 'Ignores prerequisites checks' complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from get-attester-committee" -s h -l help -d 'Print help' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from wait-for-registry" -s t -l timeout -d 'Wait timeout in seconds' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from wait-for-registry" -l poll-interval -d 'Poll interval in milliseconds' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from wait-for-registry" -l chain -d 'Chain to use' -r +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from wait-for-registry" -s v -l verbose -d 'Verbose mode' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from wait-for-registry" -l ignore-prerequisites -d 'Ignores prerequisites checks' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from wait-for-registry" -s h -l help -d 'Print help' complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from help" -f -a "set-attester-committee" -d 'Sets the attester committee in the consensus registry contract to `consensus.genesis_spec.attesters` in general.yaml' complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from help" -f -a "get-attester-committee" -d 'Fetches the attester committee from the consensus registry contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from help" -f -a "wait-for-registry" -d 'Wait until the consensus registry contract is deployed to L2' complete -c zkstack -n "__fish_zkstack_using_subcommand consensus; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c zkstack -n "__fish_zkstack_using_subcommand update" -l chain -d 'Chain to use' -r complete -c zkstack -n "__fish_zkstack_using_subcommand update" -s c -l only-config -d 'Update only the config files' @@ -703,13 +764,21 @@ complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_su complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from prover" -f -a "run" -d 'Run prover' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from prover" -f -a "init-bellman-cuda" -d 'Initialize bellman-cuda' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from prover" -f -a "compressor-keys" -d 'Download compressor keys' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from server" -f -a "build" -d 'Builds server' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from server" -f -a "run" -d 'Runs server' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from server" -f -a "wait" -d 'Waits for server to start' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from external-node" -f -a "configs" -d 'Prepare configs for EN' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from external-node" -f -a "init" -d 'Init databases' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from external-node" -f -a "build" -d 'Build external node' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from external-node" -f -a "run" -d 'Run external node' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from external-node" -f -a "wait" -d 'Wait for external node to start' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from contract-verifier" -f -a "build" -d 'Build contract verifier binary' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from contract-verifier" -f -a "run" -d 'Run contract verifier' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from contract-verifier" -f -a "wait" -d 'Wait for contract verifier to start' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from contract-verifier" -f -a "init" -d 'Download required binaries for contract verifier' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from explorer" -f -a "init" -d 'Initialize explorer (create database to store explorer data and generate docker compose file with explorer services). Runs for all chains, unless --chain is passed' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from explorer" -f -a "run-backend" -d 'Start explorer backend services (api, data_fetcher, worker) for a given chain. Uses default chain, unless --chain is passed' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from explorer" -f -a "run" -d 'Run explorer app' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from consensus" -f -a "set-attester-committee" -d 'Sets the attester committee in the consensus registry contract to `consensus.genesis_spec.attesters` in general.yaml' complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from consensus" -f -a "get-attester-committee" -d 'Fetches the attester committee from the consensus registry contract' +complete -c zkstack -n "__fish_zkstack_using_subcommand help; and __fish_seen_subcommand_from consensus" -f -a "wait-for-registry" -d 'Wait until the consensus registry contract is deployed to L2' diff --git a/zkstack_cli/crates/zkstack/completion/zkstack.sh b/zkstack_cli/crates/zkstack/completion/zkstack.sh index 6261941e10f5..0cf89ed4ef3f 100644 --- a/zkstack_cli/crates/zkstack/completion/zkstack.sh +++ b/zkstack_cli/crates/zkstack/completion/zkstack.sh @@ -195,6 +195,9 @@ _zkstack() { zkstack__consensus,set-attester-committee) cmd="zkstack__consensus__set__attester__committee" ;; + zkstack__consensus,wait-for-registry) + cmd="zkstack__consensus__wait__for__registry" + ;; zkstack__consensus__help,get-attester-committee) cmd="zkstack__consensus__help__get__attester__committee" ;; @@ -204,6 +207,12 @@ _zkstack() { zkstack__consensus__help,set-attester-committee) cmd="zkstack__consensus__help__set__attester__committee" ;; + zkstack__consensus__help,wait-for-registry) + cmd="zkstack__consensus__help__wait__for__registry" + ;; + zkstack__contract__verifier,build) + cmd="zkstack__contract__verifier__build" + ;; zkstack__contract__verifier,help) cmd="zkstack__contract__verifier__help" ;; @@ -213,6 +222,12 @@ _zkstack() { zkstack__contract__verifier,run) cmd="zkstack__contract__verifier__run" ;; + zkstack__contract__verifier,wait) + cmd="zkstack__contract__verifier__wait" + ;; + zkstack__contract__verifier__help,build) + cmd="zkstack__contract__verifier__help__build" + ;; zkstack__contract__verifier__help,help) cmd="zkstack__contract__verifier__help__help" ;; @@ -222,6 +237,9 @@ _zkstack() { zkstack__contract__verifier__help,run) cmd="zkstack__contract__verifier__help__run" ;; + zkstack__contract__verifier__help,wait) + cmd="zkstack__contract__verifier__help__wait" + ;; zkstack__dev,clean) cmd="zkstack__dev__clean" ;; @@ -663,6 +681,9 @@ _zkstack() { zkstack__explorer__help,run-backend) cmd="zkstack__explorer__help__run__backend" ;; + zkstack__external__node,build) + cmd="zkstack__external__node__build" + ;; zkstack__external__node,configs) cmd="zkstack__external__node__configs" ;; @@ -675,6 +696,12 @@ _zkstack() { zkstack__external__node,run) cmd="zkstack__external__node__run" ;; + zkstack__external__node,wait) + cmd="zkstack__external__node__wait" + ;; + zkstack__external__node__help,build) + cmd="zkstack__external__node__help__build" + ;; zkstack__external__node__help,configs) cmd="zkstack__external__node__help__configs" ;; @@ -687,6 +714,9 @@ _zkstack() { zkstack__external__node__help,run) cmd="zkstack__external__node__help__run" ;; + zkstack__external__node__help,wait) + cmd="zkstack__external__node__help__wait" + ;; zkstack__help,autocomplete) cmd="zkstack__help__autocomplete" ;; @@ -789,12 +819,21 @@ _zkstack() { zkstack__help__consensus,set-attester-committee) cmd="zkstack__help__consensus__set__attester__committee" ;; + zkstack__help__consensus,wait-for-registry) + cmd="zkstack__help__consensus__wait__for__registry" + ;; + zkstack__help__contract__verifier,build) + cmd="zkstack__help__contract__verifier__build" + ;; zkstack__help__contract__verifier,init) cmd="zkstack__help__contract__verifier__init" ;; zkstack__help__contract__verifier,run) cmd="zkstack__help__contract__verifier__run" ;; + zkstack__help__contract__verifier,wait) + cmd="zkstack__help__contract__verifier__wait" + ;; zkstack__help__dev,clean) cmd="zkstack__help__dev__clean" ;; @@ -942,6 +981,9 @@ _zkstack() { zkstack__help__explorer,run-backend) cmd="zkstack__help__explorer__run__backend" ;; + zkstack__help__external__node,build) + cmd="zkstack__help__external__node__build" + ;; zkstack__help__external__node,configs) cmd="zkstack__help__external__node__configs" ;; @@ -951,6 +993,9 @@ _zkstack() { zkstack__help__external__node,run) cmd="zkstack__help__external__node__run" ;; + zkstack__help__external__node,wait) + cmd="zkstack__help__external__node__wait" + ;; zkstack__help__prover,compressor-keys) cmd="zkstack__help__prover__compressor__keys" ;; @@ -966,6 +1011,15 @@ _zkstack() { zkstack__help__prover,setup-keys) cmd="zkstack__help__prover__setup__keys" ;; + zkstack__help__server,build) + cmd="zkstack__help__server__build" + ;; + zkstack__help__server,run) + cmd="zkstack__help__server__run" + ;; + zkstack__help__server,wait) + cmd="zkstack__help__server__wait" + ;; zkstack__prover,compressor-keys) cmd="zkstack__prover__compressor__keys" ;; @@ -1002,6 +1056,30 @@ _zkstack() { zkstack__prover__help,setup-keys) cmd="zkstack__prover__help__setup__keys" ;; + zkstack__server,build) + cmd="zkstack__server__build" + ;; + zkstack__server,help) + cmd="zkstack__server__help" + ;; + zkstack__server,run) + cmd="zkstack__server__run" + ;; + zkstack__server,wait) + cmd="zkstack__server__wait" + ;; + zkstack__server__help,build) + cmd="zkstack__server__help__build" + ;; + zkstack__server__help,help) + cmd="zkstack__server__help__help" + ;; + zkstack__server__help,run) + cmd="zkstack__server__help__run" + ;; + zkstack__server__help,wait) + cmd="zkstack__server__help__wait" + ;; *) ;; esac @@ -2144,7 +2222,7 @@ _zkstack() { return 0 ;; zkstack__consensus) - opts="-v -h --verbose --chain --ignore-prerequisites --help set-attester-committee get-attester-committee help" + opts="-v -h --verbose --chain --ignore-prerequisites --help set-attester-committee get-attester-committee wait-for-registry help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2180,7 +2258,7 @@ _zkstack() { return 0 ;; zkstack__consensus__help) - opts="set-attester-committee get-attester-committee help" + opts="set-attester-committee get-attester-committee wait-for-registry help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2235,6 +2313,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__consensus__help__wait__for__registry) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__consensus__set__attester__committee) opts="-v -h --from-genesis --from-file --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -2257,6 +2349,36 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__consensus__wait__for__registry) + opts="-t -v -h --timeout --poll-interval --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --timeout) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -t) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --poll-interval) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__containers) opts="-o -v -h --observability --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -2284,7 +2406,7 @@ _zkstack() { return 0 ;; zkstack__contract__verifier) - opts="-v -h --verbose --chain --ignore-prerequisites --help run init help" + opts="-v -h --verbose --chain --ignore-prerequisites --help build run wait init help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2301,8 +2423,26 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__contract__verifier__build) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__contract__verifier__help) - opts="run init help" + opts="build run wait init help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2315,6 +2455,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__contract__verifier__help__build) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__contract__verifier__help__help) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then @@ -2357,6 +2511,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__contract__verifier__help__wait) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__contract__verifier__init) opts="-v -h --zksolc-version --zkvyper-version --solc-version --era-vm-solc-version --vyper-version --only --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -2413,6 +2581,36 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__contract__verifier__wait) + opts="-t -v -h --timeout --poll-interval --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --timeout) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -t) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --poll-interval) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__dev) opts="-v -h --verbose --chain --ignore-prerequisites --help database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -5140,7 +5338,7 @@ _zkstack() { return 0 ;; zkstack__external__node) - opts="-v -h --verbose --chain --ignore-prerequisites --help configs init run help" + opts="-v -h --verbose --chain --ignore-prerequisites --help configs init build run wait help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -5157,6 +5355,24 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__external__node__build) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__external__node__configs) opts="-u -v -h --db-url --db-name --l1-rpc-url --use-default --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -5188,7 +5404,7 @@ _zkstack() { return 0 ;; zkstack__external__node__help) - opts="configs init run help" + opts="configs init build run wait help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -5201,6 +5417,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__external__node__help__build) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__external__node__help__configs) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then @@ -5257,6 +5487,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__external__node__help__wait) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__external__node__init) opts="-v -h --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -5309,6 +5553,36 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__external__node__wait) + opts="-t -v -h --timeout --poll-interval --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --timeout) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -t) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --poll-interval) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__help) opts="autocomplete ecosystem chain dev prover server external-node containers contract-verifier portal explorer consensus update markdown help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -5590,7 +5864,7 @@ _zkstack() { return 0 ;; zkstack__help__consensus) - opts="set-attester-committee get-attester-committee" + opts="set-attester-committee get-attester-committee wait-for-registry" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -5631,6 +5905,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__help__consensus__wait__for__registry) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__help__containers) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -5646,7 +5934,7 @@ _zkstack() { return 0 ;; zkstack__help__contract__verifier) - opts="run init" + opts="build run wait init" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -5659,6 +5947,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__help__contract__verifier__build) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__help__contract__verifier__init) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then @@ -5687,6 +5989,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__help__contract__verifier__wait) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__help__dev) opts="database test clean snapshot lint fmt prover contracts config-writer send-transactions status generate-genesis" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -6416,7 +6732,7 @@ _zkstack() { return 0 ;; zkstack__help__external__node) - opts="configs init run" + opts="configs init build run wait" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -6429,6 +6745,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__help__external__node__build) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__help__external__node__configs) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then @@ -6471,6 +6801,20 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__help__external__node__wait) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__help__help) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -6598,7 +6942,7 @@ _zkstack() { return 0 ;; zkstack__help__server) - opts="" + opts="build run wait" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -6611,6 +6955,48 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__help__server__build) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__server__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__help__server__wait) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__help__update) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -7028,7 +7414,7 @@ _zkstack() { return 0 ;; zkstack__server) - opts="-a -v -h --components --genesis --additional-args --build --uring --verbose --chain --ignore-prerequisites --help" + opts="-a -v -h --components --genesis --additional-args --uring --verbose --chain --ignore-prerequisites --help build run wait help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -7057,6 +7443,154 @@ _zkstack() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + zkstack__server__build) + opts="-v -h --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__server__help) + opts="build run wait help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__server__help__build) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__server__help__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__server__help__run) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__server__help__wait) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__server__run) + opts="-a -v -h --components --genesis --additional-args --uring --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --components) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --additional-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zkstack__server__wait) + opts="-t -v -h --timeout --poll-interval --verbose --chain --ignore-prerequisites --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --timeout) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -t) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --poll-interval) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --chain) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; zkstack__update) opts="-c -v -h --only-config --verbose --chain --ignore-prerequisites --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then diff --git a/zkstack_cli/crates/zkstack/src/commands/args/mod.rs b/zkstack_cli/crates/zkstack/src/commands/args/mod.rs index 5fa83aadf51f..477f3a6ae9af 100644 --- a/zkstack_cli/crates/zkstack/src/commands/args/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/args/mod.rs @@ -1,9 +1,7 @@ -pub use autocomplete::*; -pub use containers::*; -pub use run_server::*; -pub use update::*; +pub use self::{autocomplete::*, containers::*, run_server::*, update::*, wait::*}; mod autocomplete; mod containers; mod run_server; mod update; +mod wait; diff --git a/zkstack_cli/crates/zkstack/src/commands/args/run_server.rs b/zkstack_cli/crates/zkstack/src/commands/args/run_server.rs index d090c0de03f9..40344c90ad05 100644 --- a/zkstack_cli/crates/zkstack/src/commands/args/run_server.rs +++ b/zkstack_cli/crates/zkstack/src/commands/args/run_server.rs @@ -1,22 +1,53 @@ -use clap::Parser; +use clap::{Parser, Subcommand}; use serde::{Deserialize, Serialize}; -use crate::messages::{ - MSG_SERVER_ADDITIONAL_ARGS_HELP, MSG_SERVER_BUILD_HELP, MSG_SERVER_COMPONENTS_HELP, - MSG_SERVER_GENESIS_HELP, MSG_SERVER_URING_HELP, +use crate::{ + commands::args::WaitArgs, + messages::{ + MSG_SERVER_ADDITIONAL_ARGS_HELP, MSG_SERVER_COMPONENTS_HELP, MSG_SERVER_GENESIS_HELP, + MSG_SERVER_URING_HELP, + }, }; +#[derive(Debug, Parser)] +#[command(args_conflicts_with_subcommands = true, flatten_help = true)] +pub struct ServerArgs { + #[command(subcommand)] + command: Option, + #[command(flatten)] + run: RunServerArgs, +} + +#[derive(Debug, Subcommand)] +pub enum ServerCommand { + /// Builds server + Build, + /// Runs server + Run(RunServerArgs), + /// Waits for server to start + Wait(WaitArgs), +} + +impl From for ServerCommand { + fn from(args: ServerArgs) -> Self { + args.command.unwrap_or(ServerCommand::Run(args.run)) + } +} + #[derive(Debug, Serialize, Deserialize, Parser)] pub struct RunServerArgs { - #[clap(long, help = MSG_SERVER_COMPONENTS_HELP)] + #[arg(long, help = MSG_SERVER_COMPONENTS_HELP)] pub components: Option>, - #[clap(long, help = MSG_SERVER_GENESIS_HELP)] + #[arg(long, help = MSG_SERVER_GENESIS_HELP)] pub genesis: bool, - #[clap(long, short)] - #[arg(trailing_var_arg = true, allow_hyphen_values = true, hide = false, help = MSG_SERVER_ADDITIONAL_ARGS_HELP)] + #[arg( + long, short, + trailing_var_arg = true, + allow_hyphen_values = true, + hide = false, + help = MSG_SERVER_ADDITIONAL_ARGS_HELP + )] additional_args: Vec, - #[clap(long, help = MSG_SERVER_BUILD_HELP)] - pub build: bool, - #[clap(help=MSG_SERVER_URING_HELP, long, default_missing_value = "true")] + #[clap(help = MSG_SERVER_URING_HELP, long, default_missing_value = "true")] pub uring: bool, } diff --git a/zkstack_cli/crates/zkstack/src/commands/args/wait.rs b/zkstack_cli/crates/zkstack/src/commands/args/wait.rs new file mode 100644 index 000000000000..a3a7e32ae8b4 --- /dev/null +++ b/zkstack_cli/crates/zkstack/src/commands/args/wait.rs @@ -0,0 +1,130 @@ +use std::{fmt, future::Future, time::Duration}; + +use anyhow::Context as _; +use clap::Parser; +use common::logger; +use reqwest::StatusCode; +use serde::{Deserialize, Serialize}; +use tokio::time::MissedTickBehavior; + +use crate::messages::{ + msg_wait_connect_err, msg_wait_non_successful_response, msg_wait_not_healthy, + msg_wait_starting_polling, msg_wait_timeout, MSG_WAIT_POLL_INTERVAL_HELP, + MSG_WAIT_TIMEOUT_HELP, +}; + +#[derive(Debug, Clone, Copy)] +enum PolledComponent { + Prometheus, + HealthCheck, +} + +impl fmt::Display for PolledComponent { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str(match self { + Self::Prometheus => "Prometheus", + Self::HealthCheck => "health check", + }) + } +} + +#[derive(Debug, Parser, Serialize, Deserialize)] +pub struct WaitArgs { + #[arg(long, short = 't', value_name = "SECONDS", help = MSG_WAIT_TIMEOUT_HELP)] + timeout: Option, + #[arg(long, value_name = "MILLIS", help = MSG_WAIT_POLL_INTERVAL_HELP, default_value_t = 100)] + poll_interval: u64, +} + +impl WaitArgs { + pub fn poll_interval(&self) -> Duration { + Duration::from_millis(self.poll_interval) + } + + pub async fn poll_prometheus(&self, port: u16, verbose: bool) -> anyhow::Result<()> { + let component = PolledComponent::Prometheus; + let url = format!("http://127.0.0.1:{port}/metrics"); + self.poll_with_timeout(component, self.poll_inner(component, &url, verbose)) + .await + } + + pub async fn poll_health_check(&self, port: u16, verbose: bool) -> anyhow::Result<()> { + let component = PolledComponent::HealthCheck; + let url = format!("http://127.0.0.1:{port}/health"); + self.poll_with_timeout(component, self.poll_inner(component, &url, verbose)) + .await + } + + pub async fn poll_with_timeout( + &self, + component: impl fmt::Display, + action: impl Future>, + ) -> anyhow::Result<()> { + match self.timeout { + None => action.await, + Some(timeout) => tokio::time::timeout(Duration::from_secs(timeout), action) + .await + .map_err(|_| anyhow::Error::msg(msg_wait_timeout(&component)))?, + } + } + + async fn poll_inner( + &self, + component: PolledComponent, + url: &str, + verbose: bool, + ) -> anyhow::Result<()> { + let poll_interval = Duration::from_millis(self.poll_interval); + let mut interval = tokio::time::interval(poll_interval); + interval.set_missed_tick_behavior(MissedTickBehavior::Skip); + + if verbose { + logger::debug(msg_wait_starting_polling(&component, url, poll_interval)); + } + + let client = reqwest::Client::builder() + .connect_timeout(poll_interval) + .build() + .context("failed to build reqwest::Client")?; + + loop { + interval.tick().await; + + let response = match client.get(url).send().await { + Ok(response) => response, + Err(err) if err.is_connect() || err.is_timeout() => { + continue; + } + Err(err) => { + return Err( + anyhow::Error::new(err).context(msg_wait_connect_err(&component, url)) + ) + } + }; + + match component { + PolledComponent::Prometheus => { + response + .error_for_status() + .with_context(|| msg_wait_non_successful_response(&component))?; + return Ok(()); + } + PolledComponent::HealthCheck => { + if response.status().is_success() { + return Ok(()); + } + + if response.status() == StatusCode::SERVICE_UNAVAILABLE { + if verbose { + logger::debug(msg_wait_not_healthy(url)); + } + } else { + response + .error_for_status() + .with_context(|| msg_wait_non_successful_response(&component))?; + } + } + } + } + } +} diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs b/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs index 1855a5943dc7..7a998efedbf2 100644 --- a/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs @@ -3,22 +3,23 @@ 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 common::{logger, wallets::Wallet}; +use common::{config::global_config, logger, wallets::Wallet}; use config::EcosystemConfig; use conv::*; use ethers::{ abi::Detokenize, contract::{FunctionCall, Multicall}, middleware::{Middleware, NonceManagerMiddleware, SignerMiddleware}, - providers::{Http, JsonRpcClient, PendingTransaction, Provider, RawCall as _}, + providers::{Http, JsonRpcClient, PendingTransaction, Provider, ProviderError, RawCall as _}, signers::{LocalWallet, Signer as _}, types::{Address, BlockId, H256}, }; +use tokio::time::MissedTickBehavior; use xshell::Shell; use zksync_consensus_crypto::ByteFmt; use zksync_consensus_roles::{attester, validator}; -use crate::{messages, utils::consensus::parse_attester_committee}; +use crate::{commands::args::WaitArgs, messages, utils::consensus::parse_attester_committee}; mod conv; mod proto; @@ -92,6 +93,8 @@ pub enum Command { SetAttesterCommittee(SetAttesterCommitteeCommand), /// Fetches the attester committee from the consensus registry contract. GetAttesterCommittee, + /// Wait until the consensus registry contract is deployed to L2. + WaitForRegistry(WaitArgs), } /// Collection of sent transactions. @@ -210,15 +213,18 @@ impl Setup { }) } + fn consensus_registry_addr(&self) -> anyhow::Result
{ + self.contracts + .l2 + .consensus_registry + .context(messages::MSG_CONSENSUS_REGISTRY_ADDRESS_NOT_CONFIGURED) + } + fn consensus_registry( &self, m: Arc, ) -> anyhow::Result> { - let addr = self - .contracts - .l2 - .consensus_registry - .context(messages::MSG_CONSENSUS_REGISTRY_ADDRESS_NOT_CONFIGURED)?; + let addr = self.consensus_registry_addr()?; Ok(abi::ConsensusRegistry::new(addr, m)) } @@ -276,6 +282,58 @@ impl Setup { parse_attester_committee(attesters).context("parse_attester_committee()") } + async fn wait_for_registry_contract_inner( + &self, + args: &WaitArgs, + verbose: bool, + ) -> anyhow::Result<()> { + let addr = self.consensus_registry_addr()?; + let provider = self.provider().context("provider()")?; + let mut interval = tokio::time::interval(args.poll_interval()); + interval.set_missed_tick_behavior(MissedTickBehavior::Skip); + + if verbose { + logger::debug(messages::msg_wait_consensus_registry_started_polling( + addr, + provider.url(), + )); + } + + loop { + interval.tick().await; + + let code = match provider.get_code(addr, None).await { + Ok(code) => code, + Err(ProviderError::HTTPError(err)) if err.is_connect() || err.is_timeout() => { + continue; + } + Err(err) => { + return Err(anyhow::Error::new(err) + .context(messages::MSG_CONSENSUS_REGISTRY_POLL_ERROR)) + } + }; + if !code.is_empty() { + logger::info(messages::msg_consensus_registry_wait_success( + addr, + code.len(), + )); + return Ok(()); + } + } + } + + async fn wait_for_registry_contract( + &self, + args: &WaitArgs, + verbose: bool, + ) -> anyhow::Result<()> { + args.poll_with_timeout( + messages::MSG_CONSENSUS_REGISTRY_WAIT_COMPONENT, + self.wait_for_registry_contract_inner(args, verbose), + ) + .await + } + async fn set_attester_committee(&self, want: &attester::Committee) -> anyhow::Result<()> { let provider = self.provider().context("provider()")?; let block_id = self.last_block(&provider).await.context("last_block()")?; @@ -410,6 +468,10 @@ impl Command { let got = setup.get_attester_committee().await?; print_attesters(&got); } + Self::WaitForRegistry(args) => { + let verbose = global_config().verbose; + setup.wait_for_registry_contract(&args, verbose).await?; + } } Ok(()) } diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/build.rs b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/build.rs new file mode 100644 index 000000000000..0ba72f6b2257 --- /dev/null +++ b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/build.rs @@ -0,0 +1,26 @@ +use anyhow::Context; +use common::{cmd::Cmd, logger}; +use config::EcosystemConfig; +use xshell::{cmd, Shell}; + +use crate::messages::{ + MSG_BUILDING_CONTRACT_VERIFIER, MSG_CHAIN_NOT_FOUND_ERR, + MSG_FAILED_TO_BUILD_CONTRACT_VERIFIER_ERR, +}; + +pub(crate) async fn build(shell: &Shell) -> anyhow::Result<()> { + let ecosystem = EcosystemConfig::from_file(shell)?; + let chain = ecosystem + .load_current_chain() + .context(MSG_CHAIN_NOT_FOUND_ERR)?; + let _dir_guard = shell.push_dir(&chain.link_to_code); + + logger::info(MSG_BUILDING_CONTRACT_VERIFIER); + + let mut cmd = Cmd::new(cmd!( + shell, + "cargo build --release --bin zksync_contract_verifier" + )); + cmd = cmd.with_force_run(); + cmd.run().context(MSG_FAILED_TO_BUILD_CONTRACT_VERIFIER_ERR) +} diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/mod.rs b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/mod.rs index 78bdc5fae7ec..e36e6ba62e7b 100644 --- a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/mod.rs @@ -1,22 +1,32 @@ -use args::init::InitContractVerifierArgs; use clap::Subcommand; use xshell::Shell; -pub mod args; -pub mod init; -pub mod run; +use self::args::init::InitContractVerifierArgs; +use crate::commands::args::WaitArgs; + +mod args; +mod build; +mod init; +mod run; +mod wait; #[derive(Subcommand, Debug)] pub enum ContractVerifierCommands { + /// Build contract verifier binary + Build, /// Run contract verifier Run, + /// Wait for contract verifier to start + Wait(WaitArgs), /// Download required binaries for contract verifier Init(InitContractVerifierArgs), } pub(crate) async fn run(shell: &Shell, args: ContractVerifierCommands) -> anyhow::Result<()> { match args { + ContractVerifierCommands::Build => build::build(shell).await, ContractVerifierCommands::Run => run::run(shell).await, + ContractVerifierCommands::Wait(args) => wait::wait(shell, args).await, ContractVerifierCommands::Init(args) => init::run(shell, args).await, } } 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 9913ec817e90..ebc33840bdea 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 --bin zksync_contract_verifier -- --config-path={config_path} --secrets-path={secrets_path}" + "cargo run --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 new file mode 100644 index 000000000000..011c888d3041 --- /dev/null +++ b/zkstack_cli/crates/zkstack/src/commands/contract_verifier/wait.rs @@ -0,0 +1,27 @@ +use anyhow::Context as _; +use common::{config::global_config, logger}; +use config::EcosystemConfig; +use xshell::Shell; + +use crate::{commands::args::WaitArgs, messages::MSG_CHAIN_NOT_FOUND_ERR}; + +pub(crate) async fn wait(shell: &Shell, args: WaitArgs) -> anyhow::Result<()> { + let ecosystem = EcosystemConfig::from_file(shell)?; + let chain = ecosystem + .load_current_chain() + .context(MSG_CHAIN_NOT_FOUND_ERR)?; + let verbose = global_config().verbose; + + let prometheus_port = chain + .get_general_config()? + .contract_verifier + .as_ref() + .context("contract verifier config not specified")? + .prometheus_port; + logger::info("Waiting for contract verifier to become alive"); + args.poll_prometheus(prometheus_port, verbose).await?; + logger::info(format!( + "Contract verifier is alive with Prometheus server bound to :{prometheus_port}" + )); + Ok(()) +} diff --git a/zkstack_cli/crates/zkstack/src/commands/external_node/build.rs b/zkstack_cli/crates/zkstack/src/commands/external_node/build.rs new file mode 100644 index 000000000000..ff15c0c77f30 --- /dev/null +++ b/zkstack_cli/crates/zkstack/src/commands/external_node/build.rs @@ -0,0 +1,23 @@ +use anyhow::Context; +use common::{cmd::Cmd, logger}; +use config::EcosystemConfig; +use xshell::{cmd, Shell}; + +use crate::messages::{MSG_BUILDING_EN, MSG_CHAIN_NOT_FOUND_ERR, MSG_FAILED_TO_BUILD_EN_ERR}; + +pub(crate) async fn build(shell: &Shell) -> anyhow::Result<()> { + let ecosystem = EcosystemConfig::from_file(shell)?; + let chain = ecosystem + .load_current_chain() + .context(MSG_CHAIN_NOT_FOUND_ERR)?; + let _dir_guard = shell.push_dir(&chain.link_to_code); + + logger::info(MSG_BUILDING_EN); + + let mut cmd = Cmd::new(cmd!( + shell, + "cargo build --release --bin zksync_external_node" + )); + cmd = cmd.with_force_run(); + cmd.run().context(MSG_FAILED_TO_BUILD_EN_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 095566d24e87..7bd366d5871c 100644 --- a/zkstack_cli/crates/zkstack/src/commands/external_node/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/external_node/mod.rs @@ -1,12 +1,16 @@ -use args::{prepare_configs::PrepareConfigArgs, run::RunExternalNodeArgs}; use clap::Parser; use serde::{Deserialize, Serialize}; use xshell::Shell; +use self::args::{prepare_configs::PrepareConfigArgs, run::RunExternalNodeArgs}; +use crate::commands::args::WaitArgs; + mod args; +mod build; mod init; mod prepare_configs; mod run; +mod wait; #[derive(Debug, Serialize, Deserialize, Parser)] pub enum ExternalNodeCommands { @@ -14,14 +18,20 @@ pub enum ExternalNodeCommands { Configs(PrepareConfigArgs), /// Init databases Init, + /// Build external node + Build, /// Run external node Run(RunExternalNodeArgs), + /// Wait for external node to start + Wait(WaitArgs), } pub async fn run(shell: &Shell, commands: ExternalNodeCommands) -> anyhow::Result<()> { match commands { ExternalNodeCommands::Configs(args) => prepare_configs::run(shell, args), ExternalNodeCommands::Init => init::run(shell).await, + ExternalNodeCommands::Build => build::build(shell).await, ExternalNodeCommands::Run(args) => run::run(shell, args).await, + ExternalNodeCommands::Wait(args) => wait::wait(shell, args).await, } } diff --git a/zkstack_cli/crates/zkstack/src/commands/external_node/wait.rs b/zkstack_cli/crates/zkstack/src/commands/external_node/wait.rs new file mode 100644 index 000000000000..72568c36f363 --- /dev/null +++ b/zkstack_cli/crates/zkstack/src/commands/external_node/wait.rs @@ -0,0 +1,35 @@ +use anyhow::Context as _; +use common::{config::global_config, logger}; +use config::{traits::ReadConfigWithBasePath, EcosystemConfig}; +use xshell::Shell; +use zksync_config::configs::GeneralConfig; + +use crate::{ + commands::args::WaitArgs, + messages::{msg_waiting_for_en_success, MSG_CHAIN_NOT_INITIALIZED, MSG_WAITING_FOR_EN}, +}; + +pub async fn wait(shell: &Shell, args: WaitArgs) -> anyhow::Result<()> { + let ecosystem_config = EcosystemConfig::from_file(shell)?; + let chain_config = ecosystem_config + .load_current_chain() + .context(MSG_CHAIN_NOT_INITIALIZED)?; + let verbose = global_config().verbose; + + let en_path = chain_config + .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; + + logger::info(MSG_WAITING_FOR_EN); + args.poll_health_check(health_check_port, verbose).await?; + logger::info(msg_waiting_for_en_success(health_check_port)); + Ok(()) +} diff --git a/zkstack_cli/crates/zkstack/src/commands/server.rs b/zkstack_cli/crates/zkstack/src/commands/server.rs index be7a676a8252..10f267fb8526 100644 --- a/zkstack_cli/crates/zkstack/src/commands/server.rs +++ b/zkstack_cli/crates/zkstack/src/commands/server.rs @@ -1,5 +1,7 @@ use anyhow::Context; use common::{ + cmd::Cmd, + config::global_config, logger, server::{Server, ServerMode}, }; @@ -7,25 +9,38 @@ use config::{ traits::FileConfigWithDefaultName, ChainConfig, ContractsConfig, EcosystemConfig, GeneralConfig, GenesisConfig, SecretsConfig, WalletsConfig, }; -use xshell::Shell; +use xshell::{cmd, Shell}; use crate::{ - commands::args::RunServerArgs, - messages::{MSG_CHAIN_NOT_INITIALIZED, MSG_FAILED_TO_RUN_SERVER_ERR, MSG_STARTING_SERVER}, + commands::args::{RunServerArgs, ServerArgs, ServerCommand, WaitArgs}, + messages::{ + msg_waiting_for_server_success, MSG_BUILDING_SERVER, MSG_CHAIN_NOT_INITIALIZED, + MSG_FAILED_TO_BUILD_SERVER_ERR, MSG_FAILED_TO_RUN_SERVER_ERR, MSG_STARTING_SERVER, + MSG_WAITING_FOR_SERVER, + }, }; -pub fn run(shell: &Shell, args: RunServerArgs) -> anyhow::Result<()> { +pub async fn run(shell: &Shell, args: ServerArgs) -> anyhow::Result<()> { let ecosystem_config = EcosystemConfig::from_file(shell)?; - let chain_config = ecosystem_config .load_current_chain() .context(MSG_CHAIN_NOT_INITIALIZED)?; - logger::info(MSG_STARTING_SERVER); + match ServerCommand::from(args) { + ServerCommand::Run(args) => run_server(args, &chain_config, shell), + ServerCommand::Build => build_server(&chain_config, shell), + ServerCommand::Wait(args) => wait_for_server(args, &chain_config).await, + } +} - run_server(args, &chain_config, shell)?; +fn build_server(chain_config: &ChainConfig, shell: &Shell) -> anyhow::Result<()> { + let _dir_guard = shell.push_dir(&chain_config.link_to_code); - Ok(()) + logger::info(MSG_BUILDING_SERVER); + + let mut cmd = Cmd::new(cmd!(shell, "cargo build --release --bin zksync_server")); + cmd = cmd.with_force_run(); + cmd.run().context(MSG_FAILED_TO_BUILD_SERVER_ERR) } fn run_server( @@ -33,17 +48,13 @@ fn run_server( chain_config: &ChainConfig, shell: &Shell, ) -> anyhow::Result<()> { + logger::info(MSG_STARTING_SERVER); let server = Server::new( args.components.clone(), chain_config.link_to_code.clone(), args.uring, ); - if args.build { - server.build(shell)?; - return Ok(()); - } - let mode = if args.genesis { ServerMode::Genesis } else { @@ -62,3 +73,20 @@ fn run_server( ) .context(MSG_FAILED_TO_RUN_SERVER_ERR) } + +async fn wait_for_server(args: WaitArgs, chain_config: &ChainConfig) -> anyhow::Result<()> { + let verbose = global_config().verbose; + + let health_check_port = chain_config + .get_general_config()? + .api_config + .as_ref() + .context("no API config")? + .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)); + Ok(()) +} diff --git a/zkstack_cli/crates/zkstack/src/main.rs b/zkstack_cli/crates/zkstack/src/main.rs index 3ebe26a4fa21..8a115201fc81 100644 --- a/zkstack_cli/crates/zkstack/src/main.rs +++ b/zkstack_cli/crates/zkstack/src/main.rs @@ -15,7 +15,7 @@ use config::EcosystemConfig; use xshell::Shell; use crate::commands::{ - args::RunServerArgs, chain::ChainCommands, consensus, ecosystem::EcosystemCommands, + args::ServerArgs, chain::ChainCommands, consensus, ecosystem::EcosystemCommands, explorer::ExplorerCommands, external_node::ExternalNodeCommands, prover::ProverCommands, }; @@ -57,7 +57,7 @@ pub enum ZkStackSubcommands { #[command(subcommand, alias = "p")] Prover(ProverCommands), /// Run server - Server(RunServerArgs), + Server(ServerArgs), /// External Node related commands #[command(subcommand, alias = "en")] ExternalNode(ExternalNodeCommands), @@ -136,7 +136,7 @@ async fn run_subcommand(zkstack_args: ZkStack) -> anyhow::Result<()> { ZkStackSubcommands::Chain(args) => commands::chain::run(&shell, *args).await?, ZkStackSubcommands::Dev(args) => commands::dev::run(&shell, args).await?, ZkStackSubcommands::Prover(args) => commands::prover::run(&shell, args).await?, - ZkStackSubcommands::Server(args) => commands::server::run(&shell, args)?, + ZkStackSubcommands::Server(args) => commands::server::run(&shell, args).await?, ZkStackSubcommands::Containers(args) => commands::containers::run(&shell, args)?, ZkStackSubcommands::ExternalNode(args) => { commands::external_node::run(&shell, args).await? diff --git a/zkstack_cli/crates/zkstack/src/messages.rs b/zkstack_cli/crates/zkstack/src/messages.rs index 516194ef721e..bedcb233b19f 100644 --- a/zkstack_cli/crates/zkstack/src/messages.rs +++ b/zkstack_cli/crates/zkstack/src/messages.rs @@ -1,9 +1,10 @@ -use std::path::Path; +use std::{fmt, path::Path, time::Duration}; use ethers::{ - types::{H160, U256}, + types::{Address, H160, U256}, utils::format_ether, }; +use url::Url; use zksync_consensus_roles::attester; pub(super) const MSG_SETUP_KEYS_DOWNLOAD_SELECTION_PROMPT: &str = @@ -264,7 +265,6 @@ pub(super) const MSG_ENABLE_CONSENSUS_HELP: &str = "Enable consensus"; pub(super) const MSG_SERVER_GENESIS_HELP: &str = "Run server in genesis mode"; pub(super) const MSG_SERVER_ADDITIONAL_ARGS_HELP: &str = "Additional arguments that can be passed through the CLI"; -pub(super) const MSG_SERVER_BUILD_HELP: &str = "Build server but don't run it"; pub(super) const MSG_SERVER_URING_HELP: &str = "Enables uring support for RocksDB"; /// Accept ownership related messages @@ -284,6 +284,13 @@ pub(super) const MSG_OBSERVABILITY_RUN_PROMPT: &str = "Do you want to run observ pub(super) const MSG_STARTING_SERVER: &str = "Starting server"; pub(super) const MSG_FAILED_TO_RUN_SERVER_ERR: &str = "Failed to start server"; pub(super) const MSG_PREPARING_EN_CONFIGS: &str = "Preparing External Node config"; +pub(super) const MSG_BUILDING_SERVER: &str = "Building server"; +pub(super) const MSG_FAILED_TO_BUILD_SERVER_ERR: &str = "Failed to build server"; +pub(super) const MSG_WAITING_FOR_SERVER: &str = "Waiting for server to start"; + +pub(super) fn msg_waiting_for_server_success(health_check_port: u16) -> String { + format!("Server is alive with health check server on :{health_check_port}") +} /// Portal related messages pub(super) const MSG_PORTAL_FAILED_TO_FIND_ANY_CHAIN_ERR: &str = @@ -351,7 +358,14 @@ pub(super) const MSG_CONSENSUS_CONFIG_MISSING_ERR: &str = "Consensus config is m 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"; pub(super) const MSG_STARTING_EN: &str = "Starting external node"; +pub(super) const MSG_WAITING_FOR_EN: &str = "Waiting for external node to start"; + +pub(super) fn msg_waiting_for_en_success(health_check_port: u16) -> String { + format!("External node is alive with health check server on :{health_check_port}") +} /// Prover related messages pub(super) const MSG_GENERATING_SK_SPINNER: &str = "Generating setup keys..."; @@ -429,7 +443,10 @@ pub(super) fn msg_bucket_created(bucket_name: &str) -> String { } /// Contract verifier related messages +pub(super) const MSG_BUILDING_CONTRACT_VERIFIER: &str = "Building contract verifier"; pub(super) const MSG_RUNNING_CONTRACT_VERIFIER: &str = "Running contract verifier"; +pub(super) const MSG_FAILED_TO_BUILD_CONTRACT_VERIFIER_ERR: &str = + "Failed to build contract verifier"; pub(super) const MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR: &str = "Failed to run contract verifier"; pub(super) const MSG_INVALID_ARCH_ERR: &str = "Invalid arch"; pub(super) const MSG_GET_ZKSOLC_RELEASES_ERR: &str = "Failed to get zksolc releases"; @@ -478,6 +495,34 @@ pub(super) const MSG_DIFF_EN_GENERAL_CONFIG: &str = "Added the following fields to the external node generalconfig:"; pub(super) const MSG_UPDATING_ERA_OBSERVABILITY_SPINNER: &str = "Updating era observability..."; +/// Wait-related messages +pub(super) const MSG_WAIT_TIMEOUT_HELP: &str = "Wait timeout in seconds"; +pub(super) const MSG_WAIT_POLL_INTERVAL_HELP: &str = "Poll interval in milliseconds"; + +pub(super) fn msg_wait_starting_polling( + component: &impl fmt::Display, + url: &str, + poll_interval: Duration, +) -> String { + format!("Starting polling {component} at `{url}` each {poll_interval:?}") +} + +pub(super) fn msg_wait_timeout(component: &impl fmt::Display) -> String { + format!("timed out polling {component}") +} + +pub(super) fn msg_wait_connect_err(component: &impl fmt::Display, url: &str) -> String { + format!("failed to connect to {component} at `{url}`") +} + +pub(super) fn msg_wait_non_successful_response(component: &impl fmt::Display) -> String { + format!("non-successful {component} response") +} + +pub(super) fn msg_wait_not_healthy(url: &str) -> String { + format!("Node at `{url}` is not healthy") +} + pub(super) fn msg_diff_genesis_config(chain: &str) -> String { format!( "Found differences between chain {chain} and era genesis configs. Consider updating the chain {chain} genesis config and re-running genesis. Diff:" @@ -516,9 +561,20 @@ pub(super) const MSG_CONSENSUS_REGISTRY_ADDRESS_NOT_CONFIGURED: &str = "consensus registry address not configured"; pub(super) const MSG_CONSENSUS_GENESIS_SPEC_ATTESTERS_MISSING_IN_GENERAL_YAML: &str = "consensus.genesis_spec.attesters missing in general.yaml"; +pub(super) const MSG_CONSENSUS_REGISTRY_POLL_ERROR: &str = "failed querying L2 node"; +pub(super) const MSG_CONSENSUS_REGISTRY_WAIT_COMPONENT: &str = "main node HTTP RPC"; + pub(super) fn msg_setting_attester_committee_failed( got: &attester::Committee, want: &attester::Committee, ) -> String { format!("setting attester committee failed: got {got:?}, want {want:?}") } + +pub(super) fn msg_wait_consensus_registry_started_polling(addr: Address, url: &Url) -> String { + format!("Starting polling L2 HTTP RPC at {url} for code at {addr:?}") +} + +pub(super) fn msg_consensus_registry_wait_success(addr: Address, code_len: usize) -> String { + format!("Consensus registry is deployed at {addr:?}: {code_len} bytes") +}